带有Jersey / JAX-RS的AJAX JSONP Restful服务

我已经阅读了很多关于stackoverflow的问题,但我没有解决我的问题。

这是我的Restful服务:

@GET @Path("/GetAllProducts") @Produces(MediaType.APPLICATION_JSON) public String getAllProducts() { return "{\"name\":\"MAC\", \"quantity\":\"10\"}"; } 

它在浏览器上工作正常但是当我使用AJAX时,它没有显示错误但显示了一个弹出窗口:失败的对象[对象]

我的AJAX代码:

 $.ajax({ url: "http://localhost:8080/Restful/REST/WebService/GetAllProducts", type: 'GET', contentType: "application/json; charset=utf-8", dataType: "jsonp", success: function() { alert("Success"); }, error: function(e) { alert('Failed! ' + e); } }); 

我试图添加:“crossDomain:true”但它没有用。

请帮我! 谢谢!

首先让我解释一下我们可以调试的方法..

我们可以…

  • 更改AJAX调用中的error函数。 第一个参数实际上是jqHXR对象,而不是错误消息。 参数实际上是jqhxr, status, errorMsg 。 所以,如果我们使用该function:

     error: function(jqxhr, status, errorMsg) { alert('Failed! ' + errorMsg); } 

    我们会看到这个警报:

    在此处输入图像描述

    如果您不知道这意味着什么,在这种情况下确实没有帮助,但有时它会有所帮助。

我们可以…

  • 检查服务器日志

    在这种情况下,服务器日志不会显示任何错误,这意味着请求已成功处理并返回响应。

我们可以…

  • 使用浏览器开发工具。 对于Firefox,您应该安装Firebug 。 您可以看到请求和所有标题等

在此处输入图像描述

您可以使用callback查询参数查看请求。 还要密切关注Accept header,它读取application/javascript

Chrome具有相同类型的工具和AFAIK,它是内置的,您可以在开发人员工具下找到它。

话虽如此..

AJAX请求中的dataType设置有错误。 JSONP与JSON不同。 JSONP是从服务器发回的Javascript代码,用于由前端处理。 所以jQuery期待JSONP格式,这就是为什么它设置application/javascript的标头,这就是为什么“语法错误”消息,因为JSON格式与JSONP的语法不同。

所以要修复它,你只需要将dataType设置为json

 dataType: "json", success: function(data) { alert("Success: " + JSON.stringify(data)); }, 

现在你会看到一些东西:

  1. 成功的消息当然是:

    在此处输入图像描述

  2. 不再使用callback查询参数进行请求,因为这仅适用于JSONP协议。

    在此处输入图像描述

  3. Accept标头现在使用application/json

    在此处输入图像描述


只是一个FYI, contentType设置Content-Type标头。 这仅在我们发送信息时才有用,例如在POST请求中。


UPDATE

只是为了完整性:

我不确定你是否期待JSONP outoup,但如果你是,你需要知道的一件事是JSONP支持在JAX-RS中不是标准的。 它取决于JAX-RS实现,您需要如何配置支持。

首先,这是你的AJAX请求应该如何变为:(或类似的东西)

 $.ajax({ url: "http://localhost:8080/Restful/REST/WebService/GetAllProducts", type: 'GET', jsonp: 'callback', dataType: "jsonp", success: function(data) { alert("Success: " + JSON.stringify(data)); }, error: function(jqxhr, status, errorMsg) { alert('Failed! ' + errorMsg); } }); 

使用JSONP,请求看起来像url?callback=someFunctionToCall ,其中someFunctionToCall是服务器包装的JSON,并且是我们想要调用的Javascript函数的名称。 所以返回响应可能看起来像:

 someFunctionToCall({"name":"MAC", "quantity":"10"}) 

但是使用jQuery,我们不需要发送callback查询参数。 它的价值将随机进行。 当我测试时,这是请求和响应:

 // request .../GetAllProducts?callback=jQuery20302583482212586644_1418019088133 // response jQuery20302583482212586644_1418019088133({"name":"MAC", "quantity":"10"}) 

在返回响应时,将调用我们的success函数,传递数据,就像正常响应一样。 上面的AJAX请求将提醒上面完全相同的消息。

支持Resteasy

使用Reasteasy(至少3.xx),我们应该首先拥有Resteasy Jackson提供商

  org.jboss.resteasy resteasy-jackson2-provider provided  

我们需要做的就是将JSONP拦截器添加到我们的部署中

 org.jboss.resteasy.plugins.providers.jackson.JacksonJsonpInterceptor 

我没有得到确切的科学知识, 需要为这种支持添加哪种媒体类型,但我测试了

 @Produces({"text/javascript","application/javascript", "application/json"}) 

对于Jersey 2.x

Jersey内置了对JSONP的支持,因此我们不需要默认发行版中的任何其他依赖项。 我们只需要添加@JSONP注释。

 import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import org.glassfish.jersey.server.JSONP; @Path("/WebService") public class ProductsResource { @GET @Path("/GetAllProducts") @Produces({"application/json", "application/javascript"}) @JSONP(queryParam = "callback") public String getAllProducts() { return "{\"name\":\"MAC\", \"quantity\":\"10\"}"; } } 

使用与上面相同的jQuery代码,将得到相同的结果。 有关填充支持的更多信息,请参阅JSON