java POST JSON 到 Jersey REST 服务的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10244650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 00:11:59  来源:igfitidea点击:

Issue with POST JSON to a Jersey REST service

javaajaxjsonrestjersey

提问by nihulus

I have a problem with posting JSON to a Jersey REST service - GET is working perfectly but POST seems tricky. I've been working on this problem for awhile now, with no solution so far. Any help is much appreciated!

我在将 JSON 发布到 Jersey REST 服务时遇到问题 - GET 工作正常,但 POST 似乎很棘手。我已经研究这个问题一段时间了,到目前为止还没有解决方案。任何帮助深表感谢!

It seems it cant find the U RL to send the json?Here is what FireBug console shows:

似乎找不到发送 json 的 URL?FireBug 控制台显示的内容如下:

    POST http://localhost:9998/data 400 Bad Request
    Post source: name=Tony
    **Response Headers**
    Connection  close
    Content-Length  0
    Content-Type    text/html; charset=iso-8859-1
    Date    Fri, 20 Apr 2012 10:13:24 GMT
    **Request Headers**
    Accept  application/json, text/javascript, */*; q=0.01
    Accept-Encoding gzip, deflate
    Accept-Language sv-se,sv;q=0.8,en-us;q=0.5,en;q=0.3
    Connection  keep-alive
    Content-Length  9
    Content-Type    application/json; charset=UTF-8
    Host    localhost:9998
    Referer http://localhost:9998/static/page.html
    User-Agent  Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0
    X-Requested-With    XMLHttpRequest

I'm doing the POST as follows:

我正在按如下方式进行 POST:

<button id='btn' value="knapp" name="knapp" />
    <script type="text/javascript">
    $('#btn').click(function(){
        $.ajax({
            url: '/data',
            type: 'POST',
            contentType: 'application/json',
            data: {name:"Tony"},
            dataType: 'json'
        });
    })
</script>

Javabean class with @XmlRootElement:

带有@XmlRootElement 的 Javabean 类:

@XmlRootElement
public class StatusBean {
    private String name;

    public StatusBean() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Resource method:

资源方法:

@Path("/data")
public class PostData {
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public StatusBean post(StatusBean sb) {
        System.out.println(sb);
        return sb;
    }
}

The server, set up with Grizzly:

使用 Grizzly 设置的服务器:

public class Main {
    public static final URI BASE_URI = getBaseURI();

    public static void main(String[] args) throws IOException {
        HttpServer httpServer = startServer();

        Map<String,String> initParams = new HashMap<String, String>();
        initParams.put("com.sun.jersey.config.property.packages", "server");
        SelectorThread selector = GrizzlyWebContainerFactory.create("http://localhost:9998/", initParams );

        System.out.println(String.format("Jersey app started with WADL available at "
                + "%sapplication.wadl\nTry out %shelloworld\nHit enter to stop it...",
                BASE_URI, BASE_URI));

        System.in.read();
        httpServer.stop();
    }

    protected static HttpServer startServer() throws IOException {
        System.out.println("Starting grizzly...");

        ClassNamesResourceConfig rc = new ClassNamesResourceConfig(PostData.class);

//        rc.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, true);

        HttpServer server = GrizzlyServerFactory.createHttpServer(BASE_URI, rc);

        server.getServerConfiguration().addHttpHandler(new StaticHttpHandler(new File(".").getAbsolutePath()), "/static");

        return server;
    }

    private static int getPort(int defaultPort) {
        String port = System.getProperty("jersey.test.port");
        if (null != port) {
            try {
                return Integer.parseInt(port);
            } catch (NumberFormatException e) {
            }
        }
        return defaultPort;
    }

    private static URI getBaseURI() {
        return UriBuilder.fromUri("http://localhost/").port(getPort(9998)).build();
    }
}

回答by shashankaholic

  1. Try making your bean serializable.

    @XmlRootElement
    
    public class StatusBean implements Serializable {
    ....
    }
    
  2. Check your POST url. It should be `

    http://localhost:9998/{projectname}/{restservletmapping}/data

    For example, if my web.xml looks like this and my project name is SampleProject

    <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    

    URL would be : http://localhost:9998/SampleProject/rest/data

    You can use tools for testing REST services like SOAP UIor browser addons like POSTMAN, REST CONSOLE, etc.

  3. If above things are fine and REST service is giving response with testing tools. Then it could be problem of Cross Origin Policy in ajax.

  1. 尝试使您的 bean 可序列化。

    @XmlRootElement
    
    public class StatusBean implements Serializable {
    ....
    }
    
  2. 检查您的 POST 网址。应该是`

    http://localhost:9998/{projectname}/{restservletmapping}/data

    例如,如果我的 web.xml 看起来像这样并且我的项目名称是 SampleProject

    <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    

    URL 将是:http://localhost:9998/SampleProject/rest/data

    您可以使用工具来测试 REST 服务(如SOAP UI)或浏览器插件(如 POSTMAN、REST CONSOLE 等)。

  3. 如果以上一切正常并且 REST 服务正在使用测试工具提供响应。那么这可能是ajax中跨源策略的问题。

回答by danial

I had the same problem. The issue is that your data is not converted to JSON string automatically. So you just need to call JSON.stringify(...) on your data before posting it:

我有同样的问题。问题是您的数据不会自动转换为 JSON 字符串。所以你只需要在发布数据之前调用 JSON.stringify(...) :

<button id='btn' value="knapp" name="knapp" />
<script type="text/javascript">
$('#btn').click(function(){
    $.ajax({
        url: '/data',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({name:"Tony"}),
        dataType: 'json'
    });
})
</script>

This should work.

这应该有效。

回答by Piotr Kochański

From your server config I see that you haven't configured JAX-RS with Grizzly. On the base of that exampleyou should somehow pass such property

从您的服务器配置中,我看到您尚未使用 Grizzly 配置 JAX-RS。在该示例的基础上,您应该以某种方式传递此类属性

Map<String,String> initParams = new HashMap<String, String>();
initParams.put( "com.sun.jersey.config.property.packages", "package.with.your.StatusBean.class" );

Another configuration option is to use

另一个配置选项是使用

ResourceConfig rc = new PackagesResourceConfig("your.package.with.resources");

and start grizzly server:

并启动灰熊服务器:

GrizzlyServerFactory.createHttpServer(BASE_URI, rc);

See details: http://jersey.java.net/nonav/documentation/latest/user-guide.html(Chapter "Deploying the root resource"). Try to run first example they have.

查看详情:http: //jersey.java.net/nonav/documentation/latest/user-guide.html(“部署根资源”一章)。尝试运行他们拥有的第一个示例。

回答by nwinkler

Are you sure that the path you're posting to is complete? You should define another Pathannotation on the postmethod and use that in the URL you're posting to:

您确定要发布的路径是完整的吗?您应该Path在该post方法上定义另一个注释,并在您发布到的 URL 中使用它:

@Path("/data")
public class PostData {
    @Path("/postStatus")
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public StatusBean post(StatusBean sb) {
        System.out.println(sb);
        return sb;
    }
}

Then use the /data/postStatuspath to post your request to:

然后使用/data/postStatus路径将您的请求发布到:

<button id='btn' value="knapp" name="knapp" />
<script type="text/javascript">
    $('#btn').click(function(){
        $.ajax({
            url: '/data/postStatus',

            type: 'POST',
            contentType: 'application/json',
            data: {name:"Tony"},
            dataType: 'json'
        });
    })
</script>

回答by comeGetSome

You have probably forgotten to register the JSON mapper, i.e. Hymanson (or whatever mapper you use). The feature is not enabled automatically, you have to load the class in your ResourceConfig:

您可能忘记注册 JSON 映射器,即 Hymanson(或您使用的任何映射器)。该功能不会自动启用,您必须在 ResourceConfig 中加载该类:

org.glassfish.jersey.Hymanson.HymansonFeature.class

sample

样本

also, see JSON howto

另外,请参阅 JSON howto