基于带有Spring WebMVC REST控制器的accept头的不同响应实体体

时间:2012-11-07 15:09:07

标签: java spring rest spring-mvc xml-serialization

我有一个像这样的方法签名的控制器

@RequestMapping(value = "/{project:[A-Z0-9_+\\.\\(\\)=\\-]+}", method = RequestMethod.GET)
public ResponseEntity<Object> lookupProject(@PathVariable String project,
        @RequestParam(value = "fields", required = false) String fields,
        @RequestParam(value = "asList", required = false, defaultValue = "false") boolean asList);

我正在为JSON返回Collection<Object>Map<String, Object>。这不适合XML。我宁愿返回一个Project对象。

是否有一种干净的方法来确定将生成哪种内容类型?解决方法是另一种仅生成XML并返回Project对象的方法。我宁愿避免重复代码。

我在Spring 3.1.3-RELEASE。

5 个答案:

答案 0 :(得分:1)

根据Spring文档,您的产品参数将根据Accept返回内容,即

@RequestMapping(value="/someUrl/", produces="application/*")
public Project someControllerMethod(...)

如果方法接受application / xml,该方法将生成XML,如果是application / json,它将生成json等。

您只需要为适当的对象类型设置marshallers。

此处的文档:

http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#produces()

答案 1 :(得分:0)

要生成的内容类型取决于客户端可接受的类型。已经提到了一个使用produce属性的解决方案。另一个解决方案是使用ContentNegotiatingViewResolver,它可以根据accept头或其他机制解析视图。

请参阅文档http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.html

示例:http://www.mkyong.com/spring-mvc/spring-3-mvc-contentnegotiatingviewresolver-example/

答案 2 :(得分:0)

虽然,我认为Dardo的解决方案是最好的,您可以使用XMLHttpMessageConverter检查对象类型,如果它是Project对象则进行不同的转换。

答案 3 :(得分:0)

在Spring Framework 4.1中,您可以使用ResponseBodyAdvice来修改@ResponseBody或ResponseEntity方法在写出之前返回的值。

请参阅http://docs.spring.io/spring-framework/docs/4.1.0.RC2/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyAdvice.html

答案 4 :(得分:-3)

我最终分成了两种方法。

公共方法已重命名为lookupAsType。委托/返回

String[] fieldsArray = StringUtils.split(fields, ',');
return lookup(project, fieldsArray, asList, mediaType);

新方法lookup之前具有相同的代码,但不包含媒体类型的if子句。

if (mediaType.equals(MediaType.APPLICATION_JSON)) {
    body = projectValues;
} else if (mediaType.equals(MediaType.APPLICATION_XML)) {
    body = new Project(projectValues);
} else {
    throw new NotImplementedException("Project lookup is not implemented for media type '" + mediaType + "'");
}

糟糕的是,MediaType不是一个枚举,而是一个丑陋的类。