SpringMVC对PathVariable的特殊字符.的处理默认是文件后缀

        作为程序狗,生命不息,bug不止。在“止”这些bug的征程上,很讨厌遇到奇奇怪怪的bug,也很开心遇到这些奇奇怪怪的bug。通过暴露的这些bug,愈挫愈勇的去掌握欠缺的某个技术点或思维点。

       对,一个痛苦而开心的过程。

bug现象:

A组件的接口实现逻辑上用到了访问B组件的关于使用名字去查询某表记录的接口。奇怪的是,当通过再正常不过的http请求访问时

String bUrl = "http://127.0.0.1:8184/user/%s";
String username = "123@.12";
LinkedHashMap map = HttpRequestUtils.requestForObject(RequestMethod.GET,
           String.format(bUrl, username), null, LinkedHashMap.class);
//B组件接口接到的username不是123@.12而是123@,
//如果请求的是123@...12,会变成123@..,也就是丢掉最后一个.及后边的字符,
//这样参数变了,自然返回的结果就不是正确的了

B组件被访问的接口类似这样:

 @RequestMapping(value = "/user/{username}", method = {RequestMethod.GET})
 @ResponseBody
 public LinkedHashMap getUserById(@PathVariable("username") String username) {
     LinkedHashMap<String, String> result = new LinkedHashMap<>();
     //......余下代码省略
 }

是的,真是个神奇的bug。貌似A组件很无辜,它传递的参数无误呀,B组件也很无辜,从接到参数那个刻参数就不对了,怪我吗?经过查验,A、B组件上都不含有任何对请求url的字符内容上的拦截或过滤处理。

所以喽,好奇怪呀。

其实B组件一点儿都不无辜,就是它的问题。

原因:

SpringMVC对PathVariable标注的路径的参数的处理上默认.后面的是文件后缀,

用于url,例如:http://127.0.0.1:8080/user/login.html或者http://127.0.0.1:8080/user/login.do

所以,B组件接到的参数就是123@了,总是丢掉最后一个.以及后边的字符。

解决办法:

@RequestMapping(value = "/user/{username:.*}", method = {RequestMethod.GET})

在url声明上使用:.*来表示获取整个参数,不将.后的内容做文件后缀处理。

是的,这属于SpingMVC对特殊字符的处理

特别要指出的是: 关于特殊字符有是需要特别限制约定,例如点,需要在业务上特别指出不能使用单个点作为用户名,不然对于本文的例子来说,单个点的话,不能进入B组件的接口里(http://127.0.0.1:8080/user/.会解析成http://127.0.0.1:8080/user根本不是/user/{username}接口,存在接口访问异常417的bug。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值