如果 @PathVariable 包含点(.),会被截断
1、概览
使用 Spring 的 @PathVariable
和 @RequestMapping
来映射包含点的请求时,最后一个 URI 路径变量的值被会截断。
2、原因
具体来说,Spring 认为最后一个点后面的任何内容都是文件扩展名,如 .json
或 .xml
,因此,它会截断值以检索路径变量。
来看一个使用路径变量的例子:
@RestController
public class CustomController {
@GetMapping("/example/{firstValue}/{secondValue}")
public void example(@PathVariable("firstValue") String firstValue,
@PathVariable("secondValue") String secondValue) {
// ...
}
}
如上,考虑以下请求 URL 以及 firstValue
和 secondValue
变量的值:
example/gallery/link
:firstValue = "gallery"
,secondValue = "link"
。example/gallery.df/link.ar URL
:firstValue = "gallery.df "
,secondValue = "link"
example/gallery.df/link.com.ar
:firstValue = "gallery.df"
,secondValue = "link.com"
可以看到,第一个变量不受影响,但第二个带点(.
)的变量总是被截断。
3、解决办法
解决这种不便的方法之一是修改 @PathVariable
定义,添加一个 regex
(正则)映射。这样,任何点(包括最后一个点)都将被视为参数的一部分:
@GetMapping("/example/{firstValue}/{secondValue:.+}")
public void example(
@PathVariable("firstValue") String firstValue,
@PathVariable("secondValue") String secondValue) {
//...
}
避免这一问题的另一种方法是在 @PathVariable
末尾添加斜线。包围第二个变量,使其不受 Spring 默认行为的影响:
@GetMapping("/example/{firstValue}/{secondValue}/")
上述两种解决方案适用于单个请求映射。
如果想在全局 MVC 层面更改行为,就需要提供自定义配置。为此,可以实现配置类 WebMvcConfigurer
并覆写其 configurePathMatch(PathMatchConfigurer configurer)
方法来调整 PathMatchConfigurer
。
package cn.springdoc.demo.configuration;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
// 在匹配请求模式时是否使用后缀模式匹配(".*")。
configurer.setUseSuffixPatternMatch(false);
}
}
注意,这种方法会影响所有 URL。
3.1、弃用警告
自 Spring 5.2.4 起,setUseSuffixPatternMatch(boolean)
方法已被弃用,以阻止在请求路由和内容协商中使用路径扩展(后缀)。从根本上说,当前的实现很难保护 Web 应用免受 反射式文件下载(RFD) 攻击。
此外,自 Spring Framework 5.3 起,后缀模式匹配将仅适用于明确注册的后缀,以防止任意扩展(后缀)。
总之,从 Spring 5.3 开始,不需要使用 setUseSuffixPatternMatch(false)
,因为它默认已被禁用。
4、总结
本文介绍了如何解决在 Spring MVC 中使用 @PathVariable
处理带点(.
) 的 URI 路径参数时,参数值被截断的问题。
Ref:https://www.baeldung.com/spring-mvc-pathvariable-dot