Spring Boot中WebMvcConfigurer配置外部UTF-8编码资源失效问题
问题原因分析
你遇到的问题核心在于Spring的PathResourceResolver对包含非ASCII字符(如印地语字符)的外部资源路径进行安全校验时出现了误判,从失败日志的警告信息可以明确看出:
- 系统错误地将编码后的非ASCII文件名路径判定为包含
../格式的非法路径,触发了路径遍历防护机制 - 校验资源归属时,因文件名编码处理逻辑问题,
file:../../test/404ए.html被误判为不在允许的file:../../test根目录范围内
而classpath下的资源不受影响,是因为classpath资源的路径校验逻辑与外部文件系统不同,且不会触发同样的编码相关误判。
解决方法
方法1:使用绝对路径替代相对路径
将外部资源的相对路径file:../../test改为绝对路径,明确资源根目录,避免相对路径在编码处理时触发校验误判。
修改后的配置代码:
@Configuration public class StaticResourceConfiguration implements WebMvcConfigurer { private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "file:/your/absolute/path/to/test/", // 替换为实际的绝对路径 "classpath:/static/" }; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS); } }
方法2:自定义PathResourceResolver调整校验逻辑
如果必须使用相对路径,可以自定义资源解析器,修复非ASCII路径的校验逻辑:
@Configuration public class StaticResourceConfiguration implements WebMvcConfigurer { private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "file:../../test", "classpath:/static/" }; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS) .resourceChain(true) .addResolver(new PathResourceResolver() { @Override protected boolean isInvalidEncodedPath(String path) { // 先解码再校验,避免非ASCII编码被误判为非法路径 try { String decodedPath = URLDecoder.decode(path, StandardCharsets.UTF_8.name()); return decodedPath.contains("../") || decodedPath.contains("..\\"); } catch (UnsupportedEncodingException e) { return super.isInvalidEncodedPath(path); } } @Override protected Resource getResource(String resourcePath, Resource location) throws IOException { Resource resource = super.getResource(resourcePath, location); // 手动校验资源可用性,覆盖默认的归属判断逻辑 if (resource != null && resource.exists() && resource.isReadable()) { return resource; } return null; } }); } }
方法3:配置全局资源编码
在application.properties中添加编码配置,确保Spring使用UTF-8处理资源路径:
spring.http.encoding.force=true spring.http.encoding.charset=UTF-8 spring.http.encoding.enabled=true spring.mvc.pathmatch.matching-strategy=ant_path_matcher
内容的提问来源于stack exchange,提问作者Smart Guy
相关产品推荐
相关产品推荐

