springMVC數據綁定流程

springMVC數據綁定流程

  1. springMVC框架將ServletRequest對象及方法的如參實例傳遞給WebDataBinderFactory石麗以創建DataBinder對象。
  2. DataBinder調用裝配在springMVC上下文的ConversionService組件進行數據類型轉換、數據格式化(類型轉換和格式化是一起的一會來看源碼),將Servlet中的請求信息填充到如參的對象中。
  3. 調用Validator組件對已經完成綁定了的請求消息的入參對象進行數據合法性校驗,把最終生成數據綁定結果BindingData對象
  4. 如果在數據類型轉換、格式化和校驗的過程中出現錯誤的話,會把處理的結果放到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修飾,爲目標方法如參類名第一個字母小寫)。
12,13行,分別進行數據的綁定和校驗。
來看一下創建的binder對象。

這個對象中就包括了數據的轉換格式化(conversionService,從名字上就能看出來,包含了Formatting和Conversion),使用數據校驗(validators)組件完成的數據效驗,如果在數據轉換格式化或者是嬌豔過程中出現錯誤會把結果放在綁定結果(bindingResult)中。

那麼類型轉換是怎麼用的conversionService
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
這個就完成了字符串和數字之間的轉換。
完成數據的轉換後,緊接着13行,進行格式化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章