在使用SpringMVC的@PathVariable注解的时候发现一个问题,就是如果参数中有.点号,那么参数会被截断。

1
2
3
4
5
6
7
8
9
@Controller
@RequestMapping("/example")
public class ExampleController {

@RequestMapping("/{param}")
public void test(@PathVariable("param") String param){
System.out.println(param);
}
}

对于不同的url,@PathVariable得到的参数为:

1
2
3
/example/test          => text
/example/test.ext => text
/example/test.ext.ext2 => text.ext

可以看出路径参数中最后一个.以及之后的文本被截断了。

这个问题有两种结局方案:

第一种方法是在@PathVariable中指定参数的正则规则:

1
2
3
4
5
6
7
8
9
@Controller
@RequestMapping("/example")
public class ExampleController {

@RequestMapping("/{param:.+}")
public void test(@PathVariable("param") String param){
System.out.println(param);
}
}

这样param参数批量的规则是.+,也就是一个或者一个以上的所有字符。这样Spring就不会截断参数了。

这个方法在Spring3/4中都适用,但不是一个完美的方法,因为你需要修改每一个使用@PathVariable的地方。

第二种方法是添加一个配置,指定让Spring不处理@PathVariable的点号:

1
2
3
4
5
6
7
@Configuration
protected static class AllResources extends WebMvcConfigurerAdapter {
@Override
public void configurePathMatch(PathMatchConfigurer matcher) {
matcher.setUseRegisteredSuffixPatternMatch(true);
}
}
1
2
3
4
<mvc:annotation-driven>
[...]
<mvc:path-matching registered-suffixes-only="true"/>
</mvc:annotation-driven>

这个方法支持Spring4。

参考资料