FileSystemResource 以内容类型 json 返回
Posted
技术标签:
【中文标题】FileSystemResource 以内容类型 json 返回【英文标题】:FileSystemResource is returned with content type json 【发布时间】:2015-01-28 13:54:17 【问题描述】:我有以下返回文件的spring mvc方法:
@RequestMapping(value = "/files/fileName", method = RequestMethod.GET)
public FileSystemResource getFiles(@PathVariable String fileName)
String path="/home/marios/Desktop/";
return new FileSystemResource(path+fileName);
我希望 ResourceHttpMessageConverter 根据其文档创建具有八位字节流类型的适当响应:
如果 JAF 不可用,则使用 application/octet-stream。
但是,尽管我正确获取文件没有问题,但结果是 Content-Type: application/json;charset=UTF-8
你能告诉我为什么会这样吗?
(我使用弹簧版本 4.1.4。我没有明确设置任何消息转换器,我知道弹簧默认加载 ResourceHttpMessageConverter 和 MappingJackson2HttpMessageConverter,因为我的类路径中有 jackson 2,因为我有其他返回 json 的 mvc 方法。
另外,如果我使用HttpEntity<FileSystemResource>
并手动设置内容类型,或者使用produces = MediaType.APPLICATION_OCTET_STREAM
指定它,它工作正常。
另请注意,在我的请求中,我没有指定任何接受的内容类型,并且不希望依赖我的客户来执行此操作)
【问题讨论】:
我想你已经回答了你自己的问题,听起来杰克逊转换器优先于资源转换器。 JAF 始终可用,除非您使用的是非常旧的 Java 版本;) 但是结果被ResourceHttpMessageConverter写入成功,因为是文件,为什么内容类型取自MappingJackson2HttpMessageConverter? 在这里查看我的答案***.com/questions/34182523/… 【参考方案1】:我最终调试了整个事情,我发现AbstractJackson2HttpMessageConverter
有一个canWrite
实现在FileSystemResource
的情况下返回true,因为它只检查类是否可序列化,以及设置的媒体类型是null 因为我没有指定在这种情况下应该支持的任何内容。
因此,它最终将 json 内容类型放入可生产的媒体类型列表中。当然ResourceHttpMessageConverter.canWrite
实现也自然返回true,但ResourceHttpMessageConverter
不返回任何可生产的媒体类型。
当写入实际响应的时间到来时,从write
方法实现中,ResourceHttpMessageConverter
的写入首先运行,因为ResourceHttpMessageConverter
在可用转换器列表中排在第一位(如果MappingJackson2HttpMessageConverter
是第一个,它会尝试调用 write
,因为它的 canWrite
返回 true 并抛出异常),并且由于已经设置了可生产的内容类型,它不会默认运行 ResourceHttpMessageConverter.getDefaultContentType
设置正确的内容类型。
如果我删除 json 转换器,一切都会正常工作,但不幸的是,我的 json 方法都不起作用。因此,指定内容类型是摆脱返回的 json 内容类型的唯一方法
【讨论】:
【参考方案2】:对于仍在寻找一段代码的人:
您应该将 FileSystemResource
包装成 ResponseEntity<>
然后确定图像的内容类型并将其作为标题附加到ResponseEntity
。
这是一个例子:
@GetMapping("/image")
public @ResponseBody ResponseEntity<FileSystemResource> getImage() throws IOException
File file = /* load your image file from anywhere */;
if (!file.exists())
//TODO: throw 404
FileSystemResource resource = new FileSystemResource(file);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(/* determine your image's media type or just set it as a constant using MediaType.<value> */);
headers.setContentLength(resource.contentLength());
return new ResponseEntity<>(resource, headers, HttpStatus.OK);
【讨论】:
以上是关于FileSystemResource 以内容类型 json 返回的主要内容,如果未能解决你的问题,请参考以下文章