代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/saveuser" method="post">
<input name="userName" value="zhangsan"></br>
<input name="age" value="17"></br>
<input name="birth" value="2019/12/18"></br>
<input name="pet.name" value="mao"></br>
<input name="pet.age" value="6 "></br>
<input type="submit" value="submit">
</form>
</body>
</html>
@Data
public class Person {
private String userNmae;
private Integer age;
private Date birth;
private Pet pet;
}
@Data
public class Pet {
private String name;
private String age;
}
@PostMapping("/saveuser")
public Person saveUser(Person person)
{
return person;
}
效果如下
http://localhost:8080/saveuser
{“userNmae”:null,“age”:17,“birth”:“2019-12-17T16:00:00.000+00:00”,“pet”:{“name”:“mao”,“age”:"6 "}}
源码如下
通过以下代码查看哪个参数解析器支持该封装对象的参数 可以得出 ServletModelAttributeMethodProcessor参数解析器可以解析
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
HandlerMethodArgumentResolver result = (HandlerMethodArgumentResolver)this.argumentResolverCache.get(parameter);
if (result == null) {
Iterator var3 = this.argumentResolvers.iterator();
while(var3.hasNext()) {
HandlerMethodArgumentResolver resolver = (HandlerMethodArgumentResolver)var3.next();
if (resolver.supportsParameter(parameter)) {
result = resolver;
this.argumentResolverCache.put(parameter, resolver);
break;
}
}
}
return result;
}
拿到参数解析器 之后
@Nullable
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
HandlerMethodArgumentResolver resolver = this.getArgumentResolver(parameter);
if (resolver == null) {
throw new IllegalArgumentException("Unsupported parameter type [" + parameter.getParameterType().getName() + "]. supportsParameter should be called first.");
} else {
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
进入查查看参数解析器是如何解析参数的
}
}
下面是参数解析器解析参数的方法
@Nullable
public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
Assert.state(mavContainer != null, "ModelAttributeMethodProcessor requires ModelAndViewContainer");
Assert.state(binderFactory != null, "ModelAttributeMethodProcessor requires WebDataBinderFactory");
String name = ModelFactory.getNameForParameter(parameter);
ModelAttribute ann = (ModelAttribute)parameter.getParameterAnnotation(ModelAttribute.class);
if (ann != null) {
对注解的处理。我们没有注解
mavContainer.setBinding(name, ann.binding());
}
Object attribute = null;
BindingResult bindingResult = null;
if (mavContainer.containsAttribute(name)) {
attribute = mavContainer.getModel().get(name);
} else {
try {
attribute = this.createAttribute(name, parameter, binderFactory, webRequest);
进入 这里是创建一个空的Person对象
} catch (BindException var10) {
if (this.isBindExceptionRequired(parameter)) {
throw var10;
}
if (parameter.getParameterType() == Optional.class) {
attribute = Optional.empty();
} else {
attribute = var10.getTarget();
}
bindingResult = var10.getBindingResult();
}
}
if (bindingResult == null) {
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
if (binder.getTarget() != null) {
if (!mavContainer.isBindingDisabled(name)) {
this.bindRequestParameters(binder, webRequest);
}
this.validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors() && this.isBindExceptionRequired(binder, parameter)) {
throw new BindException(binder.getBindingResult());
}
}
if (!parameter.getParameterType().isInstance(attribute)) {
attribute = binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter);
}
bindingResult = binder.getBindingResult();
}
Map<String, Object> bindingResultModel = bindingResult.getModel();
mavContainer.removeAttributes(bindingResultModel);
mavContainer.addAllAttributes(bindingResultModel);
return attribute;
}
protected final Object createAttribute(String attributeName, MethodParameter parameter, WebDataBinderFactory binderFactory, NativeWebRequest request) throws Exception {
String value = this.getRequestValueForAttribute(attributeName, request);
if (value != null) {
Object attribute = this.createAttributeFromRequestValue(value, attributeName, parameter, binderFactory, request);
if (attribute != null) {
return attribute;
}
}
return super.createAttribute(attributeName, parameter, binderFactory, request);
}
上面一段代码 设置了一个空的Person对象
返回
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
然后执行这一行代码,web数据绑定器,利用 converters的转换 创建一个帮定器, 并没有绑定
绑定在下面一行代码 this.bindRequestParameters(binder, webRequest); 进入
protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
ServletRequest servletRequest = (ServletRequest)request.getNativeRequest(ServletRequest.class);
获取原生的request请求
Assert.state(servletRequest != null, "No ServletRequest");
ServletRequestDataBinder servletBinder = (ServletRequestDataBinder)binder;
获取绑定器
servletBinder.bind(servletRequest);
进行绑定
进入
}
public void bind(ServletRequest request) {
MutablePropertyValues mpvs