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

Tro*_*han 4 ajax rest jquery json jax-rs

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

这是我的Restful服务:

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

它在浏览器上工作正常但是当我使用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); 
    }
});
Run Code Online (Sandbox Code Playgroud)

我试图添加:"crossDomain:true"但它没有用.

请帮我!谢谢!

Pau*_*tha 7

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

我们可以...

  • 更改errorAJAX调用中的函数.第一个参数实际上是jqHXR对象,而不是错误消息.争论实际上是jqhxr, status, errorMsg.所以,如果我们使用这个功能:

    error: function(jqxhr, status, errorMsg) {
        alert('Failed! ' + errorMsg);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    我们会看到这个警报:

    在此输入图像描述

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

我们可以...

  • 检查服务器日志

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

我们可以...

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

在此输入图像描述

您可以使用callback查询参数查看请求.还要密切关注Accept标题,即读取application/javascript

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

话虽如此..

dataTypeAJAX请求中的设置存在错误.JSONP与JSON不同.JSONP是从服务器发回的Javascript代码,用于由前端处理.所以jQuery期待JSONP格式,这就是为什么它设置了标题application/javascript,这就是为什么"语法错误"消息,因为JSON格式与JSONP的语法不同.

所以要修复它,你只需要设置dataTypejson

dataType: "json",
success: function(data) {
    alert("Success: " + JSON.stringify(data));
},
Run Code Online (Sandbox Code Playgroud)

现在你会看到一些东西:

  1. 成功的消息当然是:

    在此输入图像描述

  2. 请求不再使用callbackquery参数,因为这仅适用于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);
    }
});
Run Code Online (Sandbox Code Playgroud)

随着JSONP,请求将看起来像url?callback=someFunctionToCall,这里someFunctionToCall就是围绕JSON服务器包装,并且是我们要调用的我们的JavaScript函数的名称.所以返回响应可能看起来像:

someFunctionToCall({"name":"MAC", "quantity":"10"})
Run Code Online (Sandbox Code Playgroud)

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

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

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

支持Resteasy

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

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jackson2-provider</artifactId>
    <scope>provided</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)

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

org.jboss.resteasy.plugins.providers.jackson.JacksonJsonpInterceptor
Run Code Online (Sandbox Code Playgroud)

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

@Produces({"text/javascript","application/javascript", "application/json"})
Run Code Online (Sandbox Code Playgroud)

对于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\"}";
    }
}
Run Code Online (Sandbox Code Playgroud)

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