SpringMVC参数解析绑定的原理 https://zhuanlan.zhihu.com/p/33780880
- SpringMVC初始化时,RequestMappingHandlerAdapter类会把一些默认的参数解析器添加到argumentResolvers中。当SpringMVC接收到请求后首先根据url查找对应的HandlerMethod。
- 遍历HandlerMethod的MethodParameter数组
- 根据MethodParameter的类型来查找确认使用哪个HandlerMethodArgumentResolver,遍历所有的argumentResolvers的supportsParameter(MethodParameter parameter)方法。。如果返回true,则表示查找成功,当前MethodParameter,使用该HandlerMethodArgumentResolver。这里确认大多都是根据参数的注解已经参数的Type来确认。
- 解析参数,从request中解析出MethodParameter对应的参数,这里解析出来的结果都是String类型。
- 转换参数,把对应String转换成具体方法所需要的类型,这里就包括了基本类型、对象、List、Set、Map
@PathVariable工作原理 参考戳这
- 将/aa/{name}/bb根据/拆成 aa、{name}、bb
- 将{name}替换成(.*),并纪录key为name
- 同样将/aa/zhangsan/bb拆成aa、zhangsan、bb
- 进行正则匹配,并根据group得到name=zhangsan
- 将name=zhangsan放入request的一个attribute中
- 根据反射和标注得到pathvariable名为name
需求
根据请求url找出数据库中与之匹配的url,截取参数
实现
private Map<String, String> getPathParamFromUri(String uri, List<String> uriList){
String[] input = uri.trim().split("/");
String key = null;
Optional<String> rtn = uriList.parallelStream()
.filter(o -> matcherUrl(input, o)).findFirst();
if (rtn.isPresent()) {
key = rtn.get();
}
return matcherParamFromUrl(input, key);
}
private Map<String, String> matcherParamFromUrl(String[] input, String uri) {
Map<String, String> rtn = new HashMap<>(5);
String[] urls = uri.trim().split("/");
for (int i = 0; i < urls.length; i++) {
if (urls[i].contains("{") && urls[i].contains("}")) {
rtn.put(urls[i].replace("{", "").replace("}", ""), input[i]);
}
}
return rtn;
}
private boolean matcherUrl(String[] input, String uri) {
Assert.notBlank(uri, "uri不能为空");
String[] urls = uri.trim().split("/");
if (input.length != urls.length) {
return false;
}
for (int i = 0; i < urls.length; i++) {
if (urls[i].contains("{") && urls[i].contains("}")) {
continue;
}
if (!urls[i].equals(input[i])) {
return false;
}
}
return true;
}