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
這個就完成了字符串和數字之間的轉換。