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

标签 jquery ajax json rest jax-rs

我已经阅读了很多关于 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”,但它没有用。

请帮我!谢谢!

最佳答案

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

我们可以...

  • 更改error AJAX 调用中的函数。第一个参数实际上是 jqHXR对象,而不是错误消息。论据实际上是 jqhxr, status, errorMsg .所以如果我们使用这个函数:
    error: function(jqxhr, status, errorMsg) {
        alert('Failed! ' + errorMsg);
    }
    

    我们会看到这个警报:

    enter image description here

    如果您不知道它的含义,在这种情况下并没有真正的帮助,但有时它会有所帮助。

  • 我们可以...
  • 检查服务器日志

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

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

  • enter image description here

    您可以看到请求是通过 callback 发出的。查询参数。也密切关注Accept header ,内容为 application/javascript
    Chrome 有相同类型的工具,和 AFAIK,它是内置的,你可以在 Developer Tools 下找到它。

    话虽如此..

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

    所以要修复它,你只需要设置 dataTypejson
    dataType: "json",
    success: function(data) {
        alert("Success: " + JSON.stringify(data));
    },
    

    现在你会看到一些东西:
  • 成功信息当然是:

    enter image description here
  • 不再使用 callback 发出请求查询参数,因为这仅适用于 JSONP 协议(protocol)。

    enter image description here
  • Accept标题现在使用 application/json
    enter image description here


  • 仅供引用,contentType设置Content-Type标题。这仅在我们发送信息时有用,例如在 POST 请求中。

    更新

    只是为了完整性:

    我不确定您是否期待 JSONP outoup,但如果您期待 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

    使用 Resteasy(至少 3.x.x),我们应该首先拥有 Resteasy Jackson 提供程序
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jackson2-provider</artifactId>
        <scope>provided</scope>
    </dependency>
    

    我们需要做的就是将 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 with Padding Support 上查看更多信息

    关于jquery - 带有 Jersey/JAX-RS Restful 服务的 AJAX JSONP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27349512/

    相关文章:

    jquery - 如何使用Chosen获取取消选择的值

    带有重叠 PNG 图像的 jQuery Draggable

    javascript - 无法使用 PHP 读取 ajax 请求

    javascript - 无法显示从 asp.net web api 中的 ajax 请求接收到的数据表

    javascript - getJSON 不起作用。厌倦了js问题

    javascript - 如何包含来自另一个 php 文件的 php 验证函数

    javascript - 从 javascript 代码发布到 PHP 后端

    javascript - 在 Textarea 中的部分文本下划线

    javascript - 为什么我的 json_encode 没有在 PHP 中给出正确的值

    iOS - 如何使用变音符号正确读取 JSON 文件