2013-08-02 21 views
8

这里是一个Jersey服务:泽西岛。如何根据网址PARAM产生JSON和XML输出

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

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

    return response; 

} 

,我想回去取决于网址PARAM“格式”产生XMLJSON响应。

响应实例由jaxb2

形成我知道我可以通过使用此代码获取xmljson响应回来,如果我的Java客户机/功能测试:

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参数。

+0

如果你可以发送一个适当的'ContentType'参数,'应用程序/ json',而不是'json',那么你可以使用'MediaType.valueOf(格式)'来获得'MediaType'实例并将其与accept方法一起使用。 –

+2

您的问题是您不知道如何设置响应的内容类型,或者? – DannyMo

回答

4

您可以直接通过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(); 
} 
0

好的。由于我们谈论的是模式外的事情,请让我尝试一下:

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

不是最诚实的态度,我承认这一点,但我想你应该给它一个尝试

10

这不是你婉什么的正确方法吨。您不应该使用查询参数来确定输出格式。您已声明资源方法同时生成XML和JSON,符合标准的方法是让客户端发送正确的HTTP“Accept”头,该头声明他们能够使用哪些媒体类型。如果他们发送“Accept:application/json”,那么你的JAX-RS实现应该选择将你的方法的响应格式化为JSON,如果客户端发送“Accept:application/xml”,它应该自动将你的响应格式化为XML格式。如果客户指出他们可以接受,您的JAX-RS实现可以自由选择,你不应该在意。如果客户端指出他们也不能接受,那么你的JAX-RS应该发送一个合适的HTTP错误代码,表明他们没有办法发回正确的响应。

+0

我可能会错过smth /但是“这不是正确的方式”并不完全正确。如果他想创建一个OData服务例如呢?甚至在标准范围内,它必须使用查询参数$ format来选择输出格式。 –

+0

在我看到您的回复之前,我对OData一无所知,从未使用它。我根据当时对REST原理的了解回答了这个问题。我会说你的话,OData这样做,但仍然不正确,因为REST应该基于利用HTTP标准,并且从查询参数确定输出格式不是我所知的任何一种HTTP标准。 – user2456600

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; 
}