概述
自定义对象参数解析原理
请求参数可以封装到自定义对象参数中
@PostMapping("/saveuser")
public Person saveUser(Person person) {
return person;
}
提交表单数据
<form action="/saveuser" method="post">
姓名:<input name="userName" value="zhangsan"/>
年龄:<input name="age" value="23"/>
生日:<input name="birth" value="2021/6/10"/>
宠物姓名:<input name="pet.name" value="小白"/>
宠物年龄:<input name="pet.age" value="5"/>
<input type="submit" value="提交"/>
</form>
这就是数据绑定,页面提交的请求数据,无论是GET
、POST
请求,都可以和对象属性进行绑定
自定义类型的参数,是使用ServletModelAttributeMethodProcessor
这个参数处理器来封装POJO的。它会判断是否是简单类型
public static boolean isSimpleValueType(Class<?> type) {
return (Void.class != type && void.class != type &&
(ClassUtils.isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
Temporal.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
Locale.class == type ||
Class.class == type));
}
如果不是简单数据类型,而是自定义的参数类型,就会创建一个Web数据绑定器WebDataBinder
,数据绑定器会将请求参数的值绑定到指定的JavaBean里面。而这个JavaBean就是调用createAttribute()方法创建的空对象attribute
,这个空对象被binderFactory.createBinder()
方法封装到了数据绑定器binder
中。然后会利用底层的类型转换器,将请求过来的参数值转换成对象对应的属性类型,封装到对应的属性中。
@Override
@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 = 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 {
// Create attribute instance
try {
attribute = createAttribute(name, parameter, binderFactory, webRequest);
}
catch (BindException ex) {
if (isBindExceptionRequired(parameter)) {
// No BindingResult parameter -> fail with BindException
throw ex;
}
// Otherwise, expose null/empty value and associated BindingResult
if (parameter.getParameterType() == Optional.class) {
attribute = Optional.empty();
}
bindingResult = ex.getBindingResult();
}
}
if (bindingResult == null) {
// Bean property binding and validation;
// skipped in case of binding failure on construction.
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
if (binder.getTarget() != null) {
if (!mavContainer.isBindingDisabled(name)) {
bindRequestParameters(binder, webRequest);
}
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
throw new BindException(binder.getBindingResult());
}
}
// Value type adaptation, also covering java.util.Optional
if (!parameter.getParameterType().isInstance(attribute)) {
attribute = binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter);
}
bindingResult = binder.getBindingResult();
}
// Add resolved attribute and BindingResult at the end of the model
Map<String, Object> bindingResultModel = bindingResult.getModel();
mavContainer.removeAttributes(bindingResultModel);
mavContainer.addAllAttributes(bindingResultModel);
return attribute;
}
所以WebDataBinder
就是利用converters
将请求数据转成指定的数据类型,再次封装到JavaBean中
GenericConversionService
在设置每一个值的时候,找它里面的所有converter
,判断哪个converter可以将这个数据类型(request带来参数的字符串)转换到指定的类型(JavaBean属性对应的数据类型)
最后
以上就是缥缈小虾米为你收集整理的【Web请求处理】自定义对象参数解析原理自定义对象参数解析原理的全部内容,希望文章能够帮你解决【Web请求处理】自定义对象参数解析原理自定义对象参数解析原理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复