springboot工程中,如果把web容器改为undertow,在实现上传文件接口时,如果文件名为中文,会出现乱码问题,如果使用@PathVariable接收路径中的参数也会出现中文乱码。
要解决乱码问题,在配置文件中设置了undertow编码格式为utf-8,如下,但是不生效。
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
通过跟踪源码(跟踪过滤略)发现,HttpServletRequest对象中的charsetEncoding在解析文件时变为了null。解决方式如下:
1、添加过滤器
过滤器中强制设置编码格式为:UTF-8
/**
* 将request的编码格式改为UTF-8,否则可能出现文件上传时文件名乱码的问题
*
* @author zhuquanwen
* @version 1.0
* @date 2022/12/9 16:37
* @since jdk1.8
*/
@AllArgsConstructor
public class CharsetEncodingSetFilter extends OncePerRequestFilter {
private String charset;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
request.setCharacterEncoding(charset);
response.setCharacterEncoding(charset);
filterChain.doFilter(request, response);
}
}
2、注册过滤器
将过滤器的级别调高
/**
*
* @author zhuquanwen
* @version 1.0
* @date 2022/12/9 16:40
* @since jdk1.8
*/
@AutoConfiguration
@Slf4j
public class CharsetAutoConfiguration {
@Value("${server.servlet.encoding.charset:UTF-8}")
private String charset;
@Bean
public CharsetEncodingSetFilter charsetEncodingSetFilter() {
return new CharsetEncodingSetFilter(charset);
}
@SuppressWarnings("unchecked")
@Bean
public FilterRegistrationBean charsetFilterRegistrationBean(CharsetEncodingSetFilter charsetEncodingSetFilter) {
log.info("-----注册编码设置过滤器-------");
FilterRegistrationBean frb = new FilterRegistrationBean();
frb.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
frb.setFilter(charsetEncodingSetFilter);
frb.addUrlPatterns("/*");
frb.setName("charsetSetFilter");
log.info("-----注册编码设置过滤器结束-------");
return frb;
}
}
至此,问题解决了。