【问题标题】:Issue with POST JSON to a Jersey REST servicePOST JSON 到 Jersey REST 服务的问题
【发布时间】:2012-05-01 22:42:03
【问题描述】:

我在将 JSON 发布到 Jersey REST 服务时遇到问题 - GET 运行良好,但 POST 似乎很棘手。我一直在研究这个问题一段时间,到目前为止还没有解决方案。非常感谢任何帮助!

似乎找不到发送 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

我的 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>

带有@XmlRootElement 的Javabean 类:

@XmlRootElement
public class StatusBean {
    private String name;

    public StatusBean() {
    }

    public String getName() {
        return name;
    }

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

资源方法:

@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;
    }
}

服务器,用 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();
    }
}

【问题讨论】:

  • 检查服务器日志,是否有任何东西 - 查找异常并粘贴堆栈跟踪。
  • 服务器日志中没有任何内容,这就是问题
  • 您可以发布您的 web.xml,以便我们查看 JAX-RS 配置吗?
  • 没有 web.xml 文件,我用 Grizzly 设置了服务器,所以不需要部署或类似的东西,现在添加服务器代码。
  • 我猜您需要将 REST 配置信息传递给 Grizzly,请参阅下面的答案

标签: java ajax json rest jersey


【解决方案1】:
  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>
    

    网址是:http://localhost:9998/SampleProject/rest/data

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

  3. 如果上述情况正常并且 REST 服务正在使用测试工具给出响应。 那么可能是ajax中的Cross Origin Policy的问题。

【讨论】:

  • 我的对象是动态序列化的,不需要接口,但是它缺少setter,这让我想起了这个事实。
【解决方案2】:

我遇到了同样的问题。问题是您的数据不会自动转换为 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>

这应该可行。

【讨论】:

    【解决方案3】:

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

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

    另一个配置选项是使用

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

    并启动 grizzly 服务器:

    GrizzlyServerFactory.createHttpServer(BASE_URI, rc);
    

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

    【讨论】:

    • 好的,我检查了示例并添加了这些: Map initParams = new HashMap(); initParams.put("com.sun.jersey.config.property.packages", "server"); SelectorThread 选择器 = GrizzlyWebContainerFactory.create("localhost:9998", initParams);但仍然收到 400 个错误请求...
    【解决方案4】:

    您确定要发布的路径是完整的吗?您应该在 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;
        }
    }
    

    然后使用/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>
    

    【讨论】:

    • 他收到 400 Bad request,而不是 404 Not found,所以看起来路径没问题。
    【解决方案5】:

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

    org.glassfish.jersey.jackson.JacksonFeature.class
    

    sample

    also, see JSON howto

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-06
      • 1970-01-01
      相关资源
      最近更新 更多