繁体   English   中英

使用Spring WebMVC REST控制器基于Accept标头的不同响应实体主体

[英]Different response entity body based on accept header with Spring WebMVC REST controller

我有一个带有方法签名的控制器

@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上。

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

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

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

您只需要为适当的对象类型设置编组器即可。

此处的文档:

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

产生的内容类型将取决于客户端可接受的类型。已经提到的一种解决方案是使用Produces属性。另一种解决方案是使用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/

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

在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

我最终分为两种方法。

公共方法已重命名为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不是枚举,而是一个丑陋的类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM