4

之前一定已经回答过了,但是我的谷歌电源今天关闭了,我一直在努力解决这个问题。我们正在从旧的 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 过滤器的类是什么?是否需要任何额外的配置?我完全偏离轨道了吗?

4

2 回答 2

5

如果您的所有资源方法都返回 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 包装响应实体,具体取决于回调查询参数是否可用并调整内容类型标头。

于 2012-04-04T19:43:56.563 回答
1

所以我最终最终做的(在 Martin 的伟大响应到来之前)是创建一个过滤器和一个 ResponseWrapper 来拦截输出。代码的基础位于http://docs.oracle.com/cd/B31017_01/web.1013/b28959/filters.htm

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

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

于 2012-04-04T20:42:21.200 回答