项目Controller层为了方便,会统一加上@RestController注解,这样类下面的每一个方法返回值都会自动转换为JSON。
当项目需要返回一个文件对象时,通常会使用ResponseEntity作为返回对象。
在用SpringBoot自带的Jackson时,不知道他内部的机制是如何的,但是如果,一个Controller返回的是一个ResponseEntity对象,这个对象是一个文件流,用于浏览器端下载,使用jackson是没问题的,但在使用fastjson时,它可能默认也会把这个解析为JSON,导致出现异常无法转换。具体报错如下,请问下有没有什么好的解决方案。谢谢!
9条答案
按热度按时间thtygnil1#
it's a bug
nkkqxpd92#
请问这个问题解决了吗
v8wbuo2f3#
由于springmvc 的convert 根据http的 MediaType 来判断是否要进行处理,支持的MediaType 由构造方法给出。而fastjson 接受的是所有的mediaType,
AbstractHttpMessageConverter
protected AbstractHttpMessageConverter(MediaType supportedMediaType) {
setSupportedMediaTypes(Collections.singletonList(supportedMediaType));
}
##fastjson
public FastJsonHttpMessageConverter() {
super(MediaType.ALL);
}
##jackson
public MappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
super(objectMapper, MediaType.APPLICATION_JSON, new MediaType("application", "*+json"));
}
问题可能出在这里
imzjd6km4#
+1 没有办法解决吗
tpgth1q75#
我也碰到这个问题了啊,还没有大哥解决下?
rn0zuynd6#
这个是因为在返回的时候,默认设置了返回格式,可以在返回方法上替换下,例如:@RequestMapping(value = "/download", produces = "application/octet-stream;charset=UTF-8")
zour9fqk7#
似乎并不完全是Fastjson 的问题
Spring 版本:4.3
fastjson : 1.2.7
问题原因:
关键类:
AbstractMessageConverterMethodProcessor->writeWithMessageConverters
方法Spring会获取request的contentType,以及配置的converter支持的contentType,然后找两者都符合的类型,如果是具体的一个contentType,那么就选择该contentType, 随后传给后续的MessageConverter,后续的converter拿到contentType拿到后会查看是否是自己支持的类型,如果是则会进行序列化操作。
常规默认配置下,Spring 传给Fastjson 的contentType的类型总是text/html的,Fastjson 默认是支持all,所以就会进行序列化,导致出错。
解决办法:
最简单的方案是在控制层配置:
这样配置后,在获取 producibleMediaTypes(见上面代码) 的时候就是该指定的类型了,代码逻辑在下面:
最后指定
FastJsonHttpMessageConverter 的
supportedMediaTypes
,不要包含application/octet-stream;charset=UTF-8
but5z9lq8#
这个bug还没修复吗,springboot2.0遇到同样问题
j1dl9f469#
之前没有详细看文档,今天上来又看了一遍,原来问题已经解决了。感谢测试case