springMVC数据绑定流程
- springMVC框架将ServletRequest对象及方法的如参实例传递给WebDataBinderFactory石丽以创建DataBinder对象。
- DataBinder调用装配在springMVC上下文的ConversionService组件进行数据类型转换、数据格式化(类型转换和格式化是一起的一会来看源码),将Servlet中的请求信息填充到如参的对象中。
- 调用Validator组件对已经完成绑定了的请求消息的入参对象进行数据合法性校验,把最终生成数据绑定结果BindingData对象
- 如果在数据类型转换、格式化和校验的过程中出现错误的话,会把处理的结果放到BindingResult对象中,将它们赋给处理方法的响应入参。
public final Object resolveArgument(
MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest request, WebDataBinderFactory binderFactory)
throws Exception {
String name = ModelFactory.getNameForParameter(parameter);
Object attribute = (mavContainer.containsAttribute(name)) ?
mavContainer.getModel().get(name) : createAttribute(name, parameter, binderFactory, request);
WebDataBinder binder = binderFactory.createBinder(request, attribute, name);
if (binder.getTarget() != null) {
bindRequestParameters(binder, request);
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors()) {
if (isBindExceptionRequired(binder, parameter)) {
throw new BindException(binder.getBindingResult());
}
}
}
// Add resolved attribute and BindingResult at the end of the model
Map<String, Object> bindingResultModel = binder.getBindingResult().getModel();
mavContainer.removeAttributes(bindingResultModel);
mavContainer.addAllAttributes(bindingResultModel);
return binder.getTarget();
}
10行,创建了一个WebDataBinder对象。传入了request,目标方法的参数,还有属性名(目标方法中没有加@ModelAttribute修饰,为目标方法如参类名第一个字母小写)。
ConversionService converters =
java.lang.String -> java.lang.Boolean : org.springframework.core.convert.support.StringToBooleanConverter@343a5919
java.lang.String -> java.lang.Character : org.springframework.core.convert.support.StringToCharacterConverter@7018c855
java.lang.String -> java.lang.Enum : org.springframework.core.convert.support.StringToEnumConverterFactory@5efbc794
java.lang.String -> java.lang.Number : org.springframework.core.convert.support.StringToNumberConverterFactory@14730670
java.lang.String -> java.time.Instant: org.springframework.format.datetime.standard.InstantFormatter@381724b3
java.lang.String -> java.util.Locale : org.springframework.core.convert.support.StringToLocaleConverter@913ac16
java.lang.String -> java.util.Properties : org.springframework.core.convert.support.StringToPropertiesConverter@7d0ad4f7
java.lang.String -> java.util.UUID : org.springframework.core.convert.support.StringToUUIDConverter@38289799
java.time.Instant -> java.lang.String : org.springframework.format.datetime.standard.InstantFormatter@381724b3
java.time.ZoneId -> java.util.TimeZone : org.springframework.core.convert.support.ZoneIdToTimeZoneConverter@1731f746
java.util.Calendar -> java.lang.Long : org.springframework.format.datetime.DateFormatterRegistrar$CalendarToLongConverter@84b6b20
java.util.Calendar -> java.util.Date : org.springframework.format.datetime.DateFormatterRegistrar$CalendarToDateConverter@9f8e410
java.util.Date -> java.lang.Long : org.springframework.format.datetime.DateFormatterRegistrar$DateToLongConverter@560357e6
java....
conversionService中内建了很多转换器,可以完成大多数java类型的转换工作。譬如、java.lang.String -> java.lang.Number : org.springframework.core.convert.support.StringToNumberConverterFactory@14730670
这个就完成了字符串和数字之间的转换。