5

JAX-RS 提供了一种在@Produces. Accept) 向调用者返回信息时。

我的(工作)客户,就像客户经常做的那样,要求我通过 URL 中的扩展名指定内容类型,例如api/widgets.json. 这将迫使我有各种getWidgetsXXX()方法,一种是 with @Produces("application/json"),另一种是 with @Produces("application/xml"),等等。

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

<!-- registers extension mappings -->
<init-param>
  <param-name>jaxrs.extensions</param-name>
  <param-value>
    xml=application/xml
    json=application/json
  </param-value>
</init-param>

但是我绝对找不到关于它在现实世界中如何工作的文档。我天真地以为我可以用带有扩展名的路径注释一个方法,它会模仿Accepts标题:

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

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

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

PS我没有使用Spring。

4

4 回答 4

4

<jaxrs:server>在您的作品中添加以下内容:

<jaxrs:extensionMappings>
    <entry key="json" value="application/json" />
    <entry key="xml" value="application/xml" />
</jaxrs:extensionMappings>

来源:http ://cxf.apache.org/docs/jax-rs.html#JAX-RS-Debugging

于 2012-04-27T11:55:09.713 回答
1

不知道这是否对您有帮助,但我也面临同样的问题,在我的 JAX-RS 服务中引入类似的东西。我使用JAX-RS_Content_Negotiation实现了这个功能以下位置有关于它的详细信息。

https://docs.jboss.org/resteasy/docs/3.0.6.Final/userguide/html/JAX-RS_Content_Negotiation.html

您只需将您的媒体类型映射到您想要的值

 <context-param>
        <param-name>resteasy.media.type.mappings</param-name>
        <param-value>
          html : text/html, json : application/json, xml :           
           application/xml
       </param-value>
 </context-param>


 @GET
        @Path("/second/{param}")
        @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
        public Response printStudent(@PathParam("param") String msg) {


}

现在我可以像这样访问我的服务,并且响应是根据我放在最后的扩展名

http://localhost:8080/RESTfulExample/rest/message/second/bill.json

您可以将 .xml 或 .json 放在 url 的末尾,服务将相应地生成响应。

于 2016-06-21T22:23:06.967 回答
0

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

@javax.ws.rs.GET
@javax.ws.rs.Path("{filename}")
@javax.ws.rs.Produces("*/*")
javax.ws.rs.core.Response getDirectoryOrFileContents(
        @javax.ws.rs.PathParam("filename") String filename,
        @javax.ws.rs.core.Context javax.ws.rs.core.HttpHeaders headers);

这使您可以访问所需的文件名 - 一种猜测要传递的媒体类型的方法 - 以及完整的 HTTP 标头集(提示:use headers.getAcceptableMediaTypes()),这是另一种方式。如何平衡这两者可能是“有趣的”。(我必须这样做的代码非常特定于我的应用程序的内部模型,因此可能对您没有用处。)然后您通过构造 a 返回结果Response,这使您可以非常密切地控制客户端的内容回来。

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

于 2012-04-06T21:21:12.083 回答
0

正如您所猜测的那样,扩展名模仿了Accept标题。但是,您不得在@Path注释中声明扩展:

@Path("/widgets")
@GET
@Produces({ "application/json", "application/xml" })
public List<Widget> getWidgets();

然后您可以致电widgets.xmlwidgets.json

于 2013-10-31T11:17:47.343 回答