我现在已经解决了这个问题,这个概念很简单,但实现起来可能有点棘手。据我了解,@RequestBody
只要您提供HttpMessageConverter
可以从 http 请求转换为所需类型的类型,就可以注释任何类型。所以解决方案是:
- 实施一个
HttpMessageConverter
- 配置 spring 以便使用您
HttpMessageConverter
的。
第二部分可能有点棘手。这是因为 spring 添加了一堆默认值HttpMessageConverter
,可以处理字符串、整数、日期等常见类型,我希望这些可以继续像往常一样工作。另一个问题是,如果jackson在路径上,spring还添加了一个MappingJackson2HttpMessageConverter
用于通用json处理例如转换为具体对象、地图等。Spring 将使用HttpMessageConverter
它发现的第一个声称能够转换为您的类型的类型。MappingJackson2HttpMessageConverter
声称能够为我的对象这样做,但它不能,因此它失败并且请求失败。这可以被认为是一个错误......
我想要的链条是:
- 弹簧默认
HttpMessageConverter
s。
- 我自己的
HttpMessageConverter
- 这
MappingJackson2HttpMessageConverter
我找到了两种方法来实现这一点。首先,您可以通过 xml 显式声明它。
<mvc:annotation-driven>
<mvc:message-converters>
<!-- All converters in specific order here -->
</mvc:message-converters>
</mvc:annotation-driven>
这样做的缺点是,如果默认HttpMessageConverter
链在以后的版本中发生更改,它不会因您的配置而更改。
另一种方法是HttpMessageConverter
在 MappingJackson2HttpMessageConverter
.
@Configuration
public class MyConfiguration {
@Autowired
private RequestMappingHandlerAdapter adapter;
@Autowired
private MyHttpMessageConverter myHttpMessageConverter;
@PostConstruct
private void modify() {
List<HttpMessageConverter<?>> messageConverters = adapter.getMessageConverters();
int insertLocation = messageConverters.size() - 1;
for (int i = 0; i < messageConverters.size(); i++) {
Object messageConverter = messageConverters.get(i);
if (messageConverter instanceof MappingJackson2HttpMessageConverter) {
insertLocation = i;
}
}
messageConverters.add(insertLocation, myHttpMessageConverter);
}
}
第二种选择将继续使用“默认配置”,即使它在以后的版本中发生更改。MappingJackson2HttpMessageConverter
我认为它有点hacky,一点也不优雅,但我认为它是一个有效的解决方案的原因是,声称能够转换为它无法转换的类型似乎存在缺陷。而且您不能明确地将 a 添加HttpMessageConverter
到链中的特定位置。
现在我选择第二个选项,但你怎么做取决于你......