现象:
例如:当我们想下载附件时访问url:/affix/xxx/download时便可访问。接口如下图:
@RequestMapping(value = {"/affix/{encryptionId}/download"}, method = {RequestMethod.GET})
public void download(@PathVariable String encryptionId, HttpServletRequest request, HttpServletResponse response) {
//xxx
}
但是当我们访问/affix/xxx/download增加.xxx的后缀名时也能下载。例如访问:/affix/xxx/download.exe
这是为啥?为什么会匹配到这个Handler?
原因:
通过钻研源码,发现了springmvc在获取处理器映射器阶段会根据用户请求的url查找对应的HandlerMapping,
在查找时会通过PatternsRequestCondition类匹配url的后缀(默认时开启的),url中如果有小数点,它便会匹配成功这个Handler(过程是用/affix/xxx/download.* 去匹配请求 /affix/xxx/download.exe)
SpringMVC工作流程参考:https://blog.csdn.net/sumengnan/article/details/105381225
解决办法:
错误做法:
一开始我是自定义类继承WebMvcConfigurationSupport类,重写requestMappingHandlerMapping方法,把UseSuffixPatternMatch值设置为false可以了。
@Configuration
public class MyWebMvcConfiguration extends WebMvcConfigurationSupport {
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();
handlerMapping.setUseSuffixPatternMatch(false);//设置禁止url后缀匹配
return handlerMapping;
}
}
踩坑:
在我们环境是springboot时,并且采用了继承WebMvcConfigrutionSupport类的方式。
后来发现因为springboot自动配置类WebMvcAutoConfiguration有@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)注解,springboot就不会帮我们自动配置了,我们还需要手动配置各个组件,如ResourceHandlers 否则会导致访问静态资源的时候出现404
正确做法:
应该继承WebMvcConfigurerAdapter(虽然过时了也能用),或是实现WebMvcConfigurer接口都一样
@Configuration
public class JswWebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(false);//设置禁止url后缀匹配
}
}
相关:
类似的还有useTrailingSlashMatch属性,用于匹配尾部“/”
这就是当你访问url时尾部多加了“/”也能正常访问的原因