SpringBoot 2.x/Spring MVC如何处理@PathVariable中的编码URL(含%2F等特殊字符)
解决Spring MVC/Spring Boot 2.x中@PathVariable接收含%2F编码URL的问题
嘿,这个问题我之前帮好几个开发者踩过坑,确实挺容易懵的——毕竟默认情况下,Servlet容器和Spring MVC会把%2F自动解码成/,直接当成路径分隔符处理,导致你的@PathVariable根本拿不到完整的编码字符串。下面分两种场景给你具体的解决办法:
Spring MVC 中的处理方案
要让@PathVariable能接收形如%2FWEB-INF%2Fviews%2Fjsp%2Fhello的编码URL,需要两步配合:
第一步:修改Servlet容器配置,允许编码斜杠
以Tomcat为例,你需要在server.xml的Connector标签中添加参数,放宽对路径字符的限制:<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" relaxedPathChars="|,/" relaxedQueryChars="|,/" />(注:Tomcat 8.5及以上版本推荐用
relaxedPathChars,旧版可以用allowEncodedSlash="true",但后者安全性稍差)第二步:关闭Spring MVC的自动路径解码
即使容器允许了编码斜杠,Spring MVC默认还是会自动解码路径变量,所以需要通过配置关闭这个行为。创建一个Web配置类:@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { UrlPathHelper urlPathHelper = new UrlPathHelper(); urlPathHelper.setUrlDecode(false); // 禁止自动解码路径变量 configurer.setUrlPathHelper(urlPathHelper); } }之后你的控制器就能正常拿到原始编码值了,比如:
@Controller public class PathController { @GetMapping("/static/{encodedUrl}") public String handleEncodedPath(@PathVariable String encodedUrl) { // 这里encodedUrl就是%2FWEB-INF%2Fviews%2Fjsp%2Fhello return "success"; } }
Spring Boot 2.x 中的处理方案
Spring Boot 2.x用自动配置简化了流程,只需要两步:
第一步:配置Servlet容器允许编码斜杠
在application.properties(或application.yml)中添加Tomcat的配置:# 允许路径中包含编码的斜杠等特殊字符 server.tomcat.relaxed-path-chars=/,| server.tomcat.relaxed-query-chars=/,|第二步:关闭Spring MVC的自动路径解码
有两种方式可选:- 配置文件方式(Spring Boot 2.6+推荐)
直接在配置文件中添加:spring.mvc.pathmatch.url-decoding=false - 配置类方式
和Spring MVC的配置类似,创建一个Web配置类:@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setUrlDecode(false); } }
完成后,控制器中的
@PathVariable就能正常接收含%2F的编码字符串了。- 配置文件方式(Spring Boot 2.6+推荐)
重要注意事项
- 关闭自动解码后,所有
@PathVariable的参数都不会被自动解码,如果有其他需要解码的参数,你得手动处理,比如:String decodedPath = URLDecoder.decode(encodedUrl, StandardCharsets.UTF_8.name()); - 允许编码斜杠可能存在路径遍历的安全风险,务必对接收的路径变量做严格的合法性校验,避免恶意输入。
内容的提问来源于stack exchange,提问作者developer-guy
相关产品推荐
相关产品推荐

