简体   繁体   English

POST JSON到Jersey REST服务的问题

[英]Issue with POST JSON to a Jersey REST service

I have a problem with posting JSON to a Jersey REST service - GET is working perfectly but POST seems tricky. 我在将JSON发布到Jersey REST服务时遇到问题-GET工作正常,但POST似乎很棘手。 I've been working on this problem for awhile now, with no solution so far. 我已经在这个问题上研究了一段时间了,到目前为止还没有解决方案。 Any help is much appreciated! 任何帮助深表感谢!

It seems it cant find the U RL to send the json?Here is what FireBug console shows: 似乎找不到发送json的U RL,这是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();
    }
}
  1. Try making your bean serializable. 尝试使您的bean可序列化。

     @XmlRootElement public class StatusBean implements Serializable { .... } 
  2. Check your POST url. 检查您的POST网址。 It should be ` 应该是

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

    For example, if my web.xml looks like this and my project name is SampleProject 例如,如果我的web.xml看起来像这样,而我的项目名称是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 URL将是: http:// localhost:9998 / SampleProject / rest / data

    You can use tools for testing REST services like SOAP UI or browser addons like POSTMAN, REST CONSOLE, etc. 您可以使用工具来测试REST服务(例如SOAP UI)或浏览器插件(例如POSTMAN,REST CONSOLE等)。

  3. If above things are fine and REST service is giving response with testing tools. 如果以上情况都很好,并且REST服务正在使用测试工具进行响应。 Then it could be problem of Cross Origin Policy in ajax. 那么这可能是ajax中的跨源策略问题。

I had the same problem. 我有同样的问题。 The issue is that your data is not converted to JSON string automatically. 问题是您的数据不会自动转换为JSON字符串。 So you just need to call JSON.stringify(...) on your data before posting it: 因此,您只需要在数据上调用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. 这应该工作。

From your server config I see that you haven't configured JAX-RS with Grizzly. 从服务器配置中,我看到您尚未使用Grizzly配置JAX-RS。 On the base of that example you should somehow pass such property 在该示例的基础上,您应该以某种方式传递此类属性

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"). 查看详细信息: http : //jersey.java.net/nonav/documentation/latest/user-guide.html (第8章“部署根资源”)。 Try to run first example they have. 尝试运行他们拥有的第一个示例。

Are you sure that the path you're posting to is complete? 您确定要发布的路径是否完整? You should define another Path annotation on the post method and use that in the URL you're posting to: 您应该在post方法上定义另一个Path注释,并在要发布到的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/postStatus path 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>

You have probably forgotten to register the JSON mapper, ie Jackson (or whatever mapper you use). 您可能已经忘记注册JSON映射器,即Jackson(或您使用的任何映射器)。 The feature is not enabled automatically, you have to load the class in your ResourceConfig: 该功能不会自动启用,您必须在ResourceConfig中加载该类:

org.glassfish.jersey.jackson.JacksonFeature.class

sample 样品

also, see JSON howto 另外,请参阅JSON howto

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM