Java的Jersey,RESTful API和JSONP

时间:2012-04-04 02:04:13

标签: java json jsonp jersey

这肯定已经得到了回答,但是今天我的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过滤器的类是什么?是否需要其他配置?我完全偏离了轨道吗?

2 个答案:

答案 0 :(得分: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包装响应实体,具体取决于回调查询参数是否可用并调整内容类型标题。

答案 1 :(得分:1)

所以我最终做的事情(在马丁的出色响应出现之前)创建了一个过滤器和一个拦截输出的ResponseWrapper。代码的基础是http://docs.oracle.com/cd/B31017_01/web.1013/b28959/filters.htm

实际上,过滤器会检查回调参数是否存在。如果是这样,它会将回调预先添加到输出的JSON并在最后追加。在我们的测试中,这对我们来说非常有用,尽管它尚未得到强化。虽然我本来希望泽西能够自动处理它,但我无法正确使用jQuery(可能是我身上的东西,不是泽西岛的问题)。我们已经预先存在jQuery调用,我们正在更改URL以查看新的Jersey服务器,如果我们不这样做,我们真的不想进入每个$ .ajax调用来更改调用中的任何标头或内容类型必须。

除了小问题,泽西岛一直很好用!