在Apache CXF JAX-RS中映射扩展内容类型

Gar*_*son 5 mapping content-type cxf jax-rs

JAX-RS提供了一种指定内容类型的好方法@Produces,框架将自动从客户端的HTTP Accept头中确定最佳内容类型,并且奇迹奇妙,甚至将您的对象转换为该类型(例如使用JAXB或JSON使用Jackson )将信息返回给调用者时.

我的(工作)客户端,正如客户经常做的那样,通过请求我通过URL中的扩展名指定内容类型,使得简单的工作变得更加困难,例如api/widgets.json.这将迫使我有各种getWidgetsXXX()方法,一个与@Produces("application/json")另一个@Produces("application/xml"),等等.

但我正在使用Apache CXF,我很高兴发现我可以使用init参数配置CXF以将各种扩展映射到内容类型jaxrs.extensions!

<!-- registers extension mappings -->
<init-param>
  <param-name>jaxrs.extensions</param-name>
  <param-value>
    xml=application/xml
    json=application/json
  </param-value>
</init-param>
Run Code Online (Sandbox Code Playgroud)

但我完全没有找到关于它如何在现实世界中起作用的文档.我天真地以为我可以使用带扩展名的路径注释一个方法,它会模仿Accepts标题:

@Path("/widgets.{extension}")
@GET
@Produces({ "application/json", "application/xml" })
public List<Widget> getWidgets();
Run Code Online (Sandbox Code Playgroud)

所以我用它来调用它api/widgets.json,它返回XML!这特别奇怪,因为JAX-RS指定默认内容类型是列出的第一个.

在哪里可以找到如何使用CXF扩展内容类型映射?

PS我没有使用Spring.

Don*_*ows 0

在您的情况下,我会声明方法 @Produces 内容类型*/*(即完整的通配符),然后自己进行内容协商。您可能会看到这样的方法签名:

\n\n
@javax.ws.rs.GET\n@javax.ws.rs.Path("{filename}")\n@javax.ws.rs.Produces("*/*")\njavax.ws.rs.core.Response getDirectoryOrFileContents(\n        @javax.ws.rs.PathParam("filename") String filename,\n        @javax.ws.rs.core.Context javax.ws.rs.core.HttpHeaders headers);\n
Run Code Online (Sandbox Code Playgroud)\n\n

这使您可以访问所需的文件名 \xe2\x80\x94(猜测要传送 \xe2\x80\x94 的媒体类型的一种方式)和完整的 HTTP 标头集(提示:使用headers.getAcceptableMediaTypes()),这提供了另一种方式。如何平衡两者,很可能是\xe2\x80\x9c有趣的\xe2\x80\x9d。(我必须执行的代码非常特定于我的应用程序的内部模型,因此不太可能对您有用。)然后您通过构造 a 返回结果Response,这使您非常接近控制客户返回的内容。

\n\n

是的,这比让 CXF 为您处理所有这些事情需要更多的工作(它通常会生成大量样板来完成所有这些事情),但在复杂的情况下,您会很高兴能够进行控制。

\n