【问题标题】:Java's Jersey, RESTful API, and JSONPJava 的 Jersey、RESTful API 和 JSONP
【发布时间】:2012-04-17 17:51:54
【问题描述】:

这个问题之前一定已经回答过了,但是我的 Google 电源今天关闭了,我一直在为这个问题苦苦挣扎。我们正在从旧的 PHP 基础迁移到基于 Jersey 的 JVM 堆栈,它最终将提供一个基于 JSON 的 RESTful API,可以在许多应用程序中使用。到目前为止,一切都非常好,我们喜欢简单的 POJO 到 JSON 的转换。但是,我们正在处理跨域 JSON 请求中的困难。我们基本上所有的响应都返回 JSON(使用 @Produces("application/json") 和 com.sun.jersey.api.json.POJOMappingFeature 设置为 true)但是为了支持 JSONP,我们需要更改我们的方法以返回一个JSONWithPadding 的实例。这当然也需要我们为每个方法添加一个@QueryParam("callback") 参数,这本质上会重复我们的工作,导致需要两个方法根据是否有回调参数来响应相同的数据在请求中。显然,这不是我们想要的。

所以我们基本上尝试了几个不同的选项。作为泽西岛的新手,我相信这个问题已经解决了。我从几个地方读到我可以编写请求过滤器或者我可以扩展 JSON Provider。我理想的解决方案是不对我们的数据或逻辑层产生影响,而是有一些代码说“如果有回调参数,则用回调包围 JSON,否则只返回 JSON”。在这里找到了一个解决方案: http://jersey.576304.n2.nabble.com/JsonP-without-using-JSONWithPadding-td7015082.html

但是,该解决方案扩展了 Jackson JSON 对象,而不是默认的 JSON 提供程序。

最佳做法是什么?如果我在正确的轨道上,我可以扩展的默认 JSON 过滤器的类是什么?是否需要任何额外的配置?我完全偏离轨道了吗?

【问题讨论】:

    标签: java json jsonp jersey


    【解决方案1】:

    如果你所有的资源方法都返回 JSONWithPadding 对象,那么 Jersey 会根据请求的媒体类型自动判断它是否应该返回 JSON(即只是被它包裹的对象)或回调 - 即如果媒体类型由客户端是 application/javascript、application/x-javascript、text/ecmascript、application/ecmascript 或 text/jscript 中的任何一个,然后 Jersey 返回被回调包装的对象。如果请求的媒体类型是 application/json,Jersey 返回 JSON 对象(即不使用回调包装它)。因此,实现这项工作的一种方法是让您的资源方法生成上述所有媒体类型(包括 application/json),始终返回 JSONWithPadding 并让 Jersey 弄清楚该做什么。

    如果这对您不起作用,请告诉我们为什么它不涵盖您的用例(在 jersey.java.net 的用户处)。无论如何,在这种情况下,您可以使用 ContainerRequest/ResponseFilters。在请求过滤器中,您可以以任何方式修改请求标头(例如调整接受标头)以确保它匹配正确的资源方法。然后在响应过滤器中,您可以使用 JSONWithPadding 包装响应实体,具体取决于回调查询参数是否可用并调整内容类型标头。

    【讨论】:

    • 问题是jQuery默认发送一个Accepts *头,所以请求的MIME类型并且正在发送application/json作为请求,即使指定的类型是jsonp。我正在输入我最终在另一个答案中工作的内容,但简而言之,我在 Jersey 之外编写了一个过滤器和包装器,以检查 JSON 请求中是否存在回调参数,如果存在,则将回调添加到响应输出。不过感谢您的回复!
    【解决方案2】:

    因此,我最终(在 Martin 的出色响应出现之前)最终做的是创建一个过滤器和一个 ResponseWrapper 来拦截输出。代码基础在http://docs.oracle.com/cd/B31017_01/web.1013/b28959/filters.htm

    本质上,过滤器检查回调参数是否存在。如果是这样,它会将回调添加到输出的 JSON 并在末尾附加 )。这在我们的测试中非常有用,尽管它还没有被强化。虽然我希望 Jersey 能够自动处理它,但我无法让它正确地与 jQuery 一起工作(可能是我这边的东西,而不是 Jersey 的问题)。我们有预先存在的 jQuery 调用,我们正在更改 URL 以查看新的 Jersey Server,如果我们不这样做,我们真的不想进入每个 $.ajax 调用来更改调用中的任何标题或内容类型必须。

    除了小问题之外,Jersey 的合作非常愉快!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-22
      • 2011-02-17
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      • 2013-05-26
      相关资源
      最近更新 更多