以下是Jersey
服务:
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response service(@QueryParam("format") String format) {
if (format.equals("json")) {...}
return response;
}
我想根据 url param “格式”生成XML
或JSON
回复。
我的响应实例由jaxb2
我知道如果在我的Java客户端/功能测试中使用此代码,我可能会得到xml
或json
回复:
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 param这样做。
答案 0 :(得分:13)
这不是做你想做的事的正确方法。您不应使用查询参数来确定输出格式。您已声明您的资源方法同时生成XML和JSON,标准兼容的方法是让客户端发送正确的HTTP“Accept”标头,该标头声明它们能够使用哪种媒体类型。如果他们发送“Accept:application / json”,您的JAX-RS实现应该选择将方法的响应格式化为JSON,如果客户端发送“Accept:application / xml”,它应该自动将响应格式化为XML。如果客户端表明他们可以接受,那么您的JAX-RS实现可以自由选择,您也不应该关心。如果客户端表明他们也不能接受,那么您的JAX-RS应该发回适当的HTTP错误代码,表明他们没有办法发回适当的响应。
答案 1 :(得分:5)
您可以直接通过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();
}
答案 2 :(得分: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;
}
答案 3 :(得分:0)
确定。既然我们在谈论模式之外的事情,那么让我尝试一下:
如何在服务上使用过滤器(查找com.sun.jersey.spi.container.ResourceFilterFactory)并根据查询参数更改(或添加或覆盖)接受标头?
不是最诚实的做法,我承认,但我认为你应该试一试