10

这是一项Jersey服务:

@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response service(@QueryParam("format") String format) {

  if (format.equals("json")) {...}

  return response;

}

我想根据url 参数“格式”生成XML或响应。JSON

我的响应实例是由jaxb2

我知道如果在我的 Java 客户端/功能测试中使用以下代码,我可能会得到xmljson回复:

String content = service.path("").queryParam("myparam", "myvalue").accept(MediaType.APPLICATION_XML).get(String.class);

或者

String content = service.path("").queryParam("myparam", "myvalue").accept(MediaType.APPLICATION_JSON).get(String.class);

但我需要根据 url 参数来做。

4

4 回答 4

13

这不是做你想做的事的正确方法。您不应该使用查询参数来确定输出格式。您已声明您的资源方法同时生成 XML 和 JSON,符合标准的方法是让客户端发送正确的 HTTP“Accept”标头,该标头声明它们能够使用的媒体类型。如果他们发送“Accept: application/json”,您的 JAX-RS 实现应该选择将您的方法的响应格式化为 JSON,如果客户端发送“Accept: application/xml”,它应该自动将您的响应格式化为 XML。如果客户端表示他们可以接受其中任何一个,那么您的 JAX-RS 实现可以自由选择任何一个,您不必在意。如果客户表示他们不能接受,

于 2014-02-13T23:23:15.443 回答
6

您可以通过Response#ok(假设您要返回HTTP 200状态)方法直接设置响应实体的媒体类型

@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response service(@QueryParam("format") String format) {
    return Response
            // Set the status, entity and media type of the response.
            .ok(entity, "json".equals(format) ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML)
            .build();
}

或使用Response.ResponseBuilder#header方法

@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response service(@QueryParam("format") String format) {
    return Response
            // Set the status and Put your entity here.
            .ok(entity)
            // Add the Content-Type header to tell Jersey which format it should marshall the entity into.
            .header(HttpHeaders.CONTENT_TYPE, "json".equals(format) ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML)
            .build();
}
于 2013-08-03T12:13:21.087 回答
1

这里是完整的例子,上面的答案是对的。我也使用上述方法,但在使用 List 时遇到问题。我这样设置实体:

public Response getCoursesJSONOrXML(@QueryParam("type") String type){
    //Here we get list
    List<Course> entity= courseService.getAllCourses();
    Response response = Response
            .ok(entity, "xml".equals(type) ? MediaType.APPLICATION_XML : MediaType.APPLICATION_JSON)
            .build();
    return response;
}

之后我面临这个例外:

MessageBodyWriter not found for media type=application/json, type=class java.util.Arrays$ArrayList, genericType=class java.util.Arrays$ArrayList

阅读球衣文档后,我找到了我们需要使用GenericEntity作为课程列表的解决方案。这里的例子

@GET
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
public Response getCoursesJSONOrXML(@QueryParam("type") String type){
    //Here we get list
    List<Course> list = courseService.getAllCourses();
    GenericEntity<List<Course>> entity = new GenericEntity<List<Course>>(list) {};
    Response response = Response
            .ok(entity, "xml".equals(type) ? MediaType.APPLICATION_XML : MediaType.APPLICATION_JSON)
            .build();
    return response;
}
于 2016-01-31T09:43:55.000 回答
0

行。由于我们在这里讨论的是模式之外的事情,所以让我尝试一下:

您如何在您的服务上使用过滤器(查找 com.sun.jersey.spi.container.ResourceFilterFactory)并根据您的查询参数更改(或添加或覆盖)接受标头?

不是最诚实的方法,我承认,但我认为你应该试一试

于 2013-08-02T22:22:46.500 回答