情况是这样,在项目用调用文件服务的文件上传接口,出现存储的文件名显示为问号。
HttpHeaders requestHeaders = uploadUtility.setHeaders();
MultiValueMap<String, Object> form = uploadUtility.getMultiValueMap(files);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(form, requestHeaders);
排查下:
- 直接postman调用上传接口,中文显示正常。
- 项目编码为utf8。
- 项目解析文件名,打印控制台,正常显示。
- 查看form对象内容,已经是乱码情况。
RestTemplate内部有HttpMessageConverter接口,用于内容的转码,各种类型内容有不同的实现类。这些转换类默认编码有可能不是utf8的。
做了如下调整:
@Bean(name = "restUpload")
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = restTemplate.getMessageConverters();
for (Iterator<HttpMessageConverter<?>> iterator = list.iterator(); iterator.hasNext(); ) {
HttpMessageConverter item = iterator.next();
if (item instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter) item).setDefaultCharset(StandardCharsets.UTF_8);
} else if (item instanceof FormHttpMessageConverter) {
((FormHttpMessageConverter) item).setCharset(StandardCharsets.UTF_8);
((FormHttpMessageConverter) item).setMultipartCharset(StandardCharsets.UTF_8);
}
}
restTemplate.setMessageConverters(list);
return restTemplate;
}
有些包需要引用
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.4.4</version>
</dependency>
文件服务获取文件名
MimeUtility.decodeText(file.getOriginalFilename());
如上调整后,中文名显示为问号的问题得以解决。当然看起来这个解决方案并不是很完美。