zoukankan      html  css  js  c++  java
  • 第一节:SpringMVC—数据绑定流程分析

    一、问题引入

      在做 Restful 案例的时候,我们在控制器方法入参位置写一个 Employee 类型的参数,SpringMVC 就能把表单中各项属性封装到参数中,这是怎么做到的呢?

        //SpringMVC把表单提交的数据都封装到employee 对象中
        @RequestMapping(value = "/emp", method = RequestMethod.POST)
        public String addEmp(Employee employee) {
            System.out.println("employee = " + employee);
            employeeDao.save(employee);
            //重定向到 emps 查询所有,然后在 list.jsp 显示
            return "redirect:/emps";
        }

      SpringMVC 封装自定义类型对象的时候,JavaBean 要和页面提交的数据进行一一绑定,它是如何做到的呢?

      既然要做到前端页面提交的值与 JavaBean 的属性进行绑定:

      (1)页面提交的所有数据都是字符串;

      (2)对于 Integer age,Date birth 这样的属性,需要做一定的转换操作:

    employeName=zhangsan&age=18&gender=1
    String age = reuqest.getParameter("age");
    

      

      既然肯定会牵扯到以下操作:

      1、数据类型转换:数据绑定期间的数据类型转换?String->Integer

      2、数据格式化:数据绑定期间的数据格式化问题,比如提交的日期进行转换;

        birth=2021-11-30  ---> Date 2021.11.30  2021/11/30   2021-11-30
    

      

      3、数据校验:

        我们提交的数据必须是合法的?

        前端校验:JavaScript + 正则表达式

        后端校验:重要的数据也必须进行校验:校验成功:数据合法;校验失败:提示错误;

    二、数据绑定流程原理

      ① Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象;

      ② DataBinder 调用装配在 Spring MVC 上下文中的 ConversionService 组件进行数据类型转换、数据格式化工作。将 Servlet 中的请求信息填充到入参对象中;

      ③ 调用 Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象;

      ④ Spring MVC 抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的响应入参;

      Spring MVC 通过反射机制对目标处理方法进行解析,将请求消息绑定到处理方法的入参中。数据绑定的核心部件是 DataBinder,运行机制如下:

       

       源码分析:

    核心代码:
    ModelAttributeMethodProcessor:
        resolveArgument() 解析参数
        bindRequestParameters(binder, request); 将页面提交的数据封装到 JavaBean 的属性中
    ------------------------------------------------
        @Override
        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) {
                //将页面提交过来的数据封装到 JavaBean 的属性中
                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();
        }

    三、通过debug调试流程

      ① 查看数据绑定流程,在Employee类的set方法上设置断点调试

     

         

       WedDataBinder

     

      ② Spring MVC 上下文中内建了很多转换器,可完成大多数 Java 类型的转换工作。

    conversionService.converters=
    
    result = {LinkedHashMap@5127}  size = 97
    {GenericConverter$ConvertiblePair@5227} "java.lang.Number -> java.lang.Number" -> {GenericConversionService$ConvertersForPair@5228} "java.lang.Number -> java.lang.Number : org.springframework.core.convert.support.NumberToNumberConverterFactory@68161576"
    {GenericConverter$ConvertiblePair@5229} "java.lang.String -> java.lang.Number" -> {GenericConversionService$ConvertersForPair@5230} "java.lang.String -> java.lang.Number : org.springframework.core.convert.support.StringToNumberConverterFactory@2d148610"
    {GenericConverter$ConvertiblePair@5231} "java.lang.Number -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5232} "java.lang.Number -> java.lang.String : org.springframework.core.convert.support.ObjectToStringConverter@3c1bc3fa"
    {GenericConverter$ConvertiblePair@5233} "java.lang.String -> java.lang.Character" -> {GenericConversionService$ConvertersForPair@5234} "java.lang.String -> java.lang.Character : org.springframework.core.convert.support.StringToCharacterConverter@1cf34886"
    {GenericConverter$ConvertiblePair@5235} "java.lang.Character -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5236} "java.lang.Character -> java.lang.String : org.springframework.core.convert.support.ObjectToStringConverter@441653cb"
    {GenericConverter$ConvertiblePair@5237} "java.lang.Number -> java.lang.Character" -> {GenericConversionService$ConvertersForPair@5238} "java.lang.Number -> java.lang.Character : org.springframework.core.convert.support.NumberToCharacterConverter@4d3b795f"
    {GenericConverter$ConvertiblePair@5239} "java.lang.Character -> java.lang.Number" -> {GenericConversionService$ConvertersForPair@5240} "java.lang.Character -> java.lang.Number : org.springframework.core.convert.support.CharacterToNumberFactory@2f5d6711"
    {GenericConverter$ConvertiblePair@5241} "java.lang.String -> java.lang.Boolean" -> {GenericConversionService$ConvertersForPair@5242} "java.lang.String -> java.lang.Boolean : org.springframework.core.convert.support.StringToBooleanConverter@296cad04"
    {GenericConverter$ConvertiblePair@5243} "java.lang.Boolean -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5244} "java.lang.Boolean -> java.lang.String : org.springframework.core.convert.support.ObjectToStringConverter@5f123be9"
    {GenericConverter$ConvertiblePair@5245} "java.lang.String -> java.lang.Enum" -> {GenericConversionService$ConvertersForPair@5246} "java.lang.String -> java.lang.Enum : org.springframework.core.convert.support.StringToEnumConverterFactory@497540d5"
    {GenericConverter$ConvertiblePair@5247} "java.lang.Enum -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5248} "java.lang.Enum -> java.lang.String : org.springframework.core.convert.support.EnumToStringConverter@dd4d305"
    {GenericConverter$ConvertiblePair@5249} "java.lang.String -> java.util.Locale" -> {GenericConversionService$ConvertersForPair@5250} "java.lang.String -> java.util.Locale : org.springframework.core.convert.support.StringToLocaleConverter@411c5b36"
    {GenericConverter$ConvertiblePair@5251} "java.util.Locale -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5252} "java.util.Locale -> java.lang.String : org.springframework.core.convert.support.ObjectToStringConverter@f1ffd8f"
    {GenericConverter$ConvertiblePair@5253} "java.lang.String -> java.util.Properties" -> {GenericConversionService$ConvertersForPair@5254} "java.lang.String -> java.util.Properties : org.springframework.core.convert.support.StringToPropertiesConverter@6c0f6751"
    {GenericConverter$ConvertiblePair@5255} "java.util.Properties -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5256} "java.util.Properties -> java.lang.String : org.springframework.core.convert.support.PropertiesToStringConverter@47e8dd2e"
    {GenericConverter$ConvertiblePair@5257} "java.lang.String -> java.util.UUID" -> {GenericConversionService$ConvertersForPair@5258} "java.lang.String -> java.util.UUID : org.springframework.core.convert.support.StringToUUIDConverter@640eeb0e"
    {GenericConverter$ConvertiblePair@5259} "java.util.UUID -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5260} "java.util.UUID -> java.lang.String : org.springframework.core.convert.support.ObjectToStringConverter@140d8185"
    {GenericConverter$ConvertiblePair@5261} "[Ljava.lang.Object; -> java.util.Collection" -> {GenericConversionService$ConvertersForPair@5262} "org.springframework.core.convert.support.ArrayToCollectionConverter@32f59ba"
    {GenericConverter$ConvertiblePair@5263} "java.util.Collection -> [Ljava.lang.Object;" -> {GenericConversionService$ConvertersForPair@5264} "org.springframework.core.convert.support.CollectionToArrayConverter@2aff55c"
    {GenericConverter$ConvertiblePair@5265} "[Ljava.lang.Object; -> [Ljava.lang.Object;" -> {GenericConversionService$ConvertersForPair@5266} "org.springframework.core.convert.support.ArrayToArrayConverter@116a289c"
    {GenericConverter$ConvertiblePair@5267} "java.util.Collection -> java.util.Collection" -> {GenericConversionService$ConvertersForPair@5268} "org.springframework.core.convert.support.CollectionToCollectionConverter@6913829d"
    {GenericConverter$ConvertiblePair@5269} "java.util.Map -> java.util.Map" -> {GenericConversionService$ConvertersForPair@5270} "org.springframework.core.convert.support.MapToMapConverter@1088e48c"
    {GenericConverter$ConvertiblePair@5271} "[Ljava.lang.Object; -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5272} "org.springframework.core.convert.support.ArrayToStringConverter@6d70f6d4"
    {GenericConverter$ConvertiblePair@5273} "java.lang.String -> [Ljava.lang.Object;" -> {GenericConversionService$ConvertersForPair@5274} "org.springframework.core.convert.support.StringToArrayConverter@2d1e0d2e"
    {GenericConverter$ConvertiblePair@5275} "[Ljava.lang.Object; -> java.lang.Object" -> {GenericConversionService$ConvertersForPair@5276} "org.springframework.core.convert.support.ArrayToObjectConverter@58ec757a"
    {GenericConverter$ConvertiblePair@5277} "java.lang.Object -> [Ljava.lang.Object;" -> {GenericConversionService$ConvertersForPair@5278} "org.springframework.core.convert.support.ObjectToArrayConverter@f17566f"
    {GenericConverter$ConvertiblePair@5279} "java.util.Collection -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5280} "org.springframework.core.convert.support.CollectionToStringConverter@65bbc70f"
    {GenericConverter$ConvertiblePair@5281} "java.lang.String -> java.util.Collection" -> {GenericConversionService$ConvertersForPair@5282} "org.springframework.core.convert.support.StringToCollectionConverter@3891c1eb"
    {GenericConverter$ConvertiblePair@5283} "java.util.Collection -> java.lang.Object" -> {GenericConversionService$ConvertersForPair@5284} "org.springframework.core.convert.support.CollectionToObjectConverter@3ed2426"
    {GenericConverter$ConvertiblePair@5285} "java.lang.Object -> java.util.Collection" -> {GenericConversionService$ConvertersForPair@5286} "org.springframework.core.convert.support.ObjectToCollectionConverter@36fcae1a"
    {GenericConverter$ConvertiblePair@5287} "java.nio.ByteBuffer -> java.lang.Object" -> {GenericConversionService$ConvertersForPair@5288} "org.springframework.core.convert.support.ByteBufferConverter@dc48475"
    {GenericConverter$ConvertiblePair@5289} "java.lang.Object -> java.nio.ByteBuffer" -> {GenericConversionService$ConvertersForPair@5290} "org.springframework.core.convert.support.ByteBufferConverter@dc48475"
    {GenericConverter$ConvertiblePair@5291} "java.time.ZoneId -> java.util.TimeZone" -> {GenericConversionService$ConvertersForPair@5292} "java.time.ZoneId -> java.util.TimeZone : org.springframework.core.convert.support.ZoneIdToTimeZoneConverter@3bec82bf"
    {GenericConverter$ConvertiblePair@5293} "java.time.ZonedDateTime -> java.util.Calendar" -> {GenericConversionService$ConvertersForPair@5294} "java.time.ZonedDateTime -> java.util.Calendar : org.springframework.core.convert.support.ZonedDateTimeToCalendarConverter@514a4df0"
    {GenericConverter$ConvertiblePair@5295} "java.lang.Object -> java.lang.Object" -> {GenericConversionService$ConvertersForPair@5296} "org.springframework.core.convert.support.IdToEntityConverter@295a5bd,org.springframework.core.convert.support.ObjectToObjectConverter@2b5b7eb6"
    {GenericConverter$ConvertiblePair@5297} "java.lang.Object -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5298} "org.springframework.core.convert.support.FallbackObjectToStringConverter@747de818"
    {GenericConverter$ConvertiblePair@5299} "java.lang.Object -> java.util.Optional" -> {GenericConversionService$ConvertersForPair@5300} "org.springframework.core.convert.support.ObjectToOptionalConverter@77db0eaa"
    {GenericConverter$ConvertiblePair@5301} "java.lang.Long -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5302} "@org.springframework.format.annotation.DateTimeFormat java.lang.Long -> java.lang.String: org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory@584ce5a1,@org.springframework.format.annotation.NumberFormat java.lang.Long -> java.lang.String: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5303} "java.lang.String -> java.lang.Long" -> {GenericConversionService$ConvertersForPair@5304} "java.lang.String -> @org.springframework.format.annotation.DateTimeFormat java.lang.Long: org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory@584ce5a1,java.lang.String -> @org.springframework.format.annotation.NumberFormat java.lang.Long: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5305} "java.math.BigInteger -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5306} "@org.springframework.format.annotation.NumberFormat java.math.BigInteger -> java.lang.String: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5307} "java.lang.String -> java.math.BigInteger" -> {GenericConversionService$ConvertersForPair@5308} "java.lang.String -> @org.springframework.format.annotation.NumberFormat java.math.BigInteger: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5309} "java.lang.Float -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5310} "@org.springframework.format.annotation.NumberFormat java.lang.Float -> java.lang.String: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5311} "java.lang.String -> java.lang.Float" -> {GenericConversionService$ConvertersForPair@5312} "java.lang.String -> @org.springframework.format.annotation.NumberFormat java.lang.Float: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5313} "java.lang.Double -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5314} "@org.springframework.format.annotation.NumberFormat java.lang.Double -> java.lang.String: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5315} "java.lang.String -> java.lang.Double" -> {GenericConversionService$ConvertersForPair@5316} "java.lang.String -> @org.springframework.format.annotation.NumberFormat java.lang.Double: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5317} "java.lang.Short -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5318} "@org.springframework.format.annotation.NumberFormat java.lang.Short -> java.lang.String: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5319} "java.lang.String -> java.lang.Short" -> {GenericConversionService$ConvertersForPair@5320} "java.lang.String -> @org.springframework.format.annotation.NumberFormat java.lang.Short: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5321} "java.lang.Integer -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5322} "@org.springframework.format.annotation.NumberFormat java.lang.Integer -> java.lang.String: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5323} "java.lang.String -> java.lang.Integer" -> {GenericConversionService$ConvertersForPair@5324} "java.lang.String -> @org.springframework.format.annotation.NumberFormat java.lang.Integer: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5325} "java.lang.Byte -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5326} "@org.springframework.format.annotation.NumberFormat java.lang.Byte -> java.lang.String: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5327} "java.lang.String -> java.lang.Byte" -> {GenericConversionService$ConvertersForPair@5328} "java.lang.String -> @org.springframework.format.annotation.NumberFormat java.lang.Byte: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5329} "java.math.BigDecimal -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5330} "@org.springframework.format.annotation.NumberFormat java.math.BigDecimal -> java.lang.String: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5331} "java.lang.String -> java.math.BigDecimal" -> {GenericConversionService$ConvertersForPair@5332} "java.lang.String -> @org.springframework.format.annotation.NumberFormat java.math.BigDecimal: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@28929ed0"
    {GenericConverter$ConvertiblePair@5333} "java.util.Date -> java.lang.Long" -> {GenericConversionService$ConvertersForPair@5334} "java.util.Date -> java.lang.Long : org.springframework.format.datetime.DateFormatterRegistrar$DateToLongConverter@33349ef2,java.util.Date -> java.lang.Long : org.springframework.format.datetime.DateFormatterRegistrar$DateToLongConverter@1cb56860"
    {GenericConverter$ConvertiblePair@5335} "java.util.Date -> java.util.Calendar" -> {GenericConversionService$ConvertersForPair@5336} "java.util.Date -> java.util.Calendar : org.springframework.format.datetime.DateFormatterRegistrar$DateToCalendarConverter@236be7ba,java.util.Date -> java.util.Calendar : org.springframework.format.datetime.DateFormatterRegistrar$DateToCalendarConverter@1f338919"
    {GenericConverter$ConvertiblePair@5337} "java.util.Calendar -> java.util.Date" -> {GenericConversionService$ConvertersForPair@5338} "java.util.Calendar -> java.util.Date : org.springframework.format.datetime.DateFormatterRegistrar$CalendarToDateConverter@8675703,java.util.Calendar -> java.util.Date : org.springframework.format.datetime.DateFormatterRegistrar$CalendarToDateConverter@3f26c807"
    {GenericConverter$ConvertiblePair@5339} "java.util.Calendar -> java.lang.Long" -> {GenericConversionService$ConvertersForPair@5340} "java.util.Calendar -> java.lang.Long : org.springframework.format.datetime.DateFormatterRegistrar$CalendarToLongConverter@438cbe6e,java.util.Calendar -> java.lang.Long : org.springframework.format.datetime.DateFormatterRegistrar$CalendarToLongConverter@40f48c47"
    {GenericConverter$ConvertiblePair@5341} "java.lang.Long -> java.util.Date" -> {GenericConversionService$ConvertersForPair@5342} "java.lang.Long -> java.util.Date : org.springframework.format.datetime.DateFormatterRegistrar$LongToDateConverter@72191415,java.lang.Long -> java.util.Date : org.springframework.format.datetime.DateFormatterRegistrar$LongToDateConverter@7bf68ca1"
    {GenericConverter$ConvertiblePair@5343} "java.lang.Long -> java.util.Calendar" -> {GenericConversionService$ConvertersForPair@5344} "java.lang.Long -> java.util.Calendar : org.springframework.format.datetime.DateFormatterRegistrar$LongToCalendarConverter@5daf227f,java.lang.Long -> java.util.Calendar : org.springframework.format.datetime.DateFormatterRegistrar$LongToCalendarConverter@39dd1b39"
    {GenericConverter$ConvertiblePair@5345} "java.time.LocalDateTime -> java.time.LocalDate" -> {GenericConversionService$ConvertersForPair@5346} "java.time.LocalDateTime -> java.time.LocalDate : org.springframework.format.datetime.standard.DateTimeConverters$LocalDateTimeToLocalDateConverter@3de19ab"
    {GenericConverter$ConvertiblePair@5347} "java.time.LocalDateTime -> java.time.LocalTime" -> {GenericConversionService$ConvertersForPair@5348} "java.time.LocalDateTime -> java.time.LocalTime : org.springframework.format.datetime.standard.DateTimeConverters$LocalDateTimeToLocalTimeConverter@4c021ef5"
    {GenericConverter$ConvertiblePair@5349} "java.time.ZonedDateTime -> java.time.LocalDate" -> {GenericConversionService$ConvertersForPair@5350} "java.time.ZonedDateTime -> java.time.LocalDate : org.springframework.format.datetime.standard.DateTimeConverters$ZonedDateTimeToLocalDateConverter@681a61d0"
    {GenericConverter$ConvertiblePair@5351} "java.time.ZonedDateTime -> java.time.LocalTime" -> {GenericConversionService$ConvertersForPair@5352} "java.time.ZonedDateTime -> java.time.LocalTime : org.springframework.format.datetime.standard.DateTimeConverters$ZonedDateTimeToLocalTimeConverter@39cfbb39"
    {GenericConverter$ConvertiblePair@5353} "java.time.ZonedDateTime -> java.time.LocalDateTime" -> {GenericConversionService$ConvertersForPair@5354} "java.time.ZonedDateTime -> java.time.LocalDateTime : org.springframework.format.datetime.standard.DateTimeConverters$ZonedDateTimeToLocalDateTimeConverter@4aaffeea"
    {GenericConverter$ConvertiblePair@5355} "java.time.ZonedDateTime -> java.time.OffsetDateTime" -> {GenericConversionService$ConvertersForPair@5356} "java.time.ZonedDateTime -> java.time.OffsetDateTime : org.springframework.format.datetime.standard.DateTimeConverters$ZonedDateTimeToOffsetDateTimeConverter@1686a4fc"
    {GenericConverter$ConvertiblePair@5357} "java.time.ZonedDateTime -> java.time.Instant" -> {GenericConversionService$ConvertersForPair@5358} "java.time.ZonedDateTime -> java.time.Instant : org.springframework.format.datetime.standard.DateTimeConverters$ZonedDateTimeToInstantConverter@2d29531d"
    {GenericConverter$ConvertiblePair@5359} "java.time.OffsetDateTime -> java.time.LocalDate" -> {GenericConversionService$ConvertersForPair@5360} "java.time.OffsetDateTime -> java.time.LocalDate : org.springframework.format.datetime.standard.DateTimeConverters$OffsetDateTimeToLocalDateConverter@69fb23f2"
    {GenericConverter$ConvertiblePair@5361} "java.time.OffsetDateTime -> java.time.LocalTime" -> {GenericConversionService$ConvertersForPair@5362} "java.time.OffsetDateTime -> java.time.LocalTime : org.springframework.format.datetime.standard.DateTimeConverters$OffsetDateTimeToLocalTimeConverter@5c16d889"
    {GenericConverter$ConvertiblePair@5363} "java.time.OffsetDateTime -> java.time.LocalDateTime" -> {GenericConversionService$ConvertersForPair@5364} "java.time.OffsetDateTime -> java.time.LocalDateTime : org.springframework.format.datetime.standard.DateTimeConverters$OffsetDateTimeToLocalDateTimeConverter@7f9426b3"
    {GenericConverter$ConvertiblePair@5365} "java.time.OffsetDateTime -> java.time.ZonedDateTime" -> {GenericConversionService$ConvertersForPair@5366} "java.time.OffsetDateTime -> java.time.ZonedDateTime : org.springframework.format.datetime.standard.DateTimeConverters$OffsetDateTimeToZonedDateTimeConverter@18c233e7"
    {GenericConverter$ConvertiblePair@5367} "java.time.OffsetDateTime -> java.time.Instant" -> {GenericConversionService$ConvertersForPair@5368} "java.time.OffsetDateTime -> java.time.Instant : org.springframework.format.datetime.standard.DateTimeConverters$OffsetDateTimeToInstantConverter@289667be"
    {GenericConverter$ConvertiblePair@5369} "java.util.Calendar -> java.time.ZonedDateTime" -> {GenericConversionService$ConvertersForPair@5370} "java.util.Calendar -> java.time.ZonedDateTime : org.springframework.format.datetime.standard.DateTimeConverters$CalendarToZonedDateTimeConverter@422e30b5"
    {GenericConverter$ConvertiblePair@5371} "java.util.Calendar -> java.time.OffsetDateTime" -> {GenericConversionService$ConvertersForPair@5372} "java.util.Calendar -> java.time.OffsetDateTime : org.springframework.format.datetime.standard.DateTimeConverters$CalendarToOffsetDateTimeConverter@1cd137fd"
    {GenericConverter$ConvertiblePair@5373} "java.util.Calendar -> java.time.LocalDate" -> {GenericConversionService$ConvertersForPair@5374} "java.util.Calendar -> java.time.LocalDate : org.springframework.format.datetime.standard.DateTimeConverters$CalendarToLocalDateConverter@1585728b"
    {GenericConverter$ConvertiblePair@5375} "java.util.Calendar -> java.time.LocalTime" -> {GenericConversionService$ConvertersForPair@5376} "java.util.Calendar -> java.time.LocalTime : org.springframework.format.datetime.standard.DateTimeConverters$CalendarToLocalTimeConverter@e355c12"
    {GenericConverter$ConvertiblePair@5377} "java.util.Calendar -> java.time.LocalDateTime" -> {GenericConversionService$ConvertersForPair@5378} "java.util.Calendar -> java.time.LocalDateTime : org.springframework.format.datetime.standard.DateTimeConverters$CalendarToLocalDateTimeConverter@3d2d7ef9"
    {GenericConverter$ConvertiblePair@5379} "java.util.Calendar -> java.time.Instant" -> {GenericConversionService$ConvertersForPair@5380} "java.util.Calendar -> java.time.Instant : org.springframework.format.datetime.standard.DateTimeConverters$CalendarToInstantConverter@2856c87e"
    {GenericConverter$ConvertiblePair@5381} "java.lang.Long -> java.time.Instant" -> {GenericConversionService$ConvertersForPair@5382} "java.lang.Long -> java.time.Instant : org.springframework.format.datetime.standard.DateTimeConverters$LongToInstantConverter@16f9f6d5"
    {GenericConverter$ConvertiblePair@5383} "java.time.Instant -> java.lang.Long" -> {GenericConversionService$ConvertersForPair@5384} "java.time.Instant -> java.lang.Long : org.springframework.format.datetime.standard.DateTimeConverters$InstantToLongConverter@3208fdd4"
    {GenericConverter$ConvertiblePair@5385} "java.time.LocalDate -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5386} "@org.springframework.format.annotation.DateTimeFormat java.time.LocalDate -> java.lang.String: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.time.LocalDate -> java.lang.String : org.springframework.format.datetime.standard.TemporalAccessorPrinter@7a0fb60c"
    {GenericConverter$ConvertiblePair@5387} "java.lang.String -> java.time.LocalDate" -> {GenericConversionService$ConvertersForPair@5388} "java.lang.String -> @org.springframework.format.annotation.DateTimeFormat java.time.LocalDate: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.lang.String -> java.time.LocalDate: org.springframework.format.datetime.standard.TemporalAccessorParser@2319a8c6"
    {GenericConverter$ConvertiblePair@5389} "java.time.LocalTime -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5390} "@org.springframework.format.annotation.DateTimeFormat java.time.LocalTime -> java.lang.String: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.time.LocalTime -> java.lang.String : org.springframework.format.datetime.standard.TemporalAccessorPrinter@560a172c"
    {GenericConverter$ConvertiblePair@5391} "java.lang.String -> java.time.LocalTime" -> {GenericConversionService$ConvertersForPair@5392} "java.lang.String -> @org.springframework.format.annotation.DateTimeFormat java.time.LocalTime: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.lang.String -> java.time.LocalTime: org.springframework.format.datetime.standard.TemporalAccessorParser@1670e060"
    {GenericConverter$ConvertiblePair@5393} "java.time.LocalDateTime -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5394} "@org.springframework.format.annotation.DateTimeFormat java.time.LocalDateTime -> java.lang.String: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.time.LocalDateTime -> java.lang.String : org.springframework.format.datetime.standard.TemporalAccessorPrinter@11c88b74"
    {GenericConverter$ConvertiblePair@5395} "java.lang.String -> java.time.LocalDateTime" -> {GenericConversionService$ConvertersForPair@5396} "java.lang.String -> @org.springframework.format.annotation.DateTimeFormat java.time.LocalDateTime: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.lang.String -> java.time.LocalDateTime: org.springframework.format.datetime.standard.TemporalAccessorParser@7f794e13"
    {GenericConverter$ConvertiblePair@5397} "java.time.ZonedDateTime -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5398} "@org.springframework.format.annotation.DateTimeFormat java.time.ZonedDateTime -> java.lang.String: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.time.ZonedDateTime -> java.lang.String : org.springframework.format.datetime.standard.TemporalAccessorPrinter@794c95a7"
    {GenericConverter$ConvertiblePair@5399} "java.lang.String -> java.time.ZonedDateTime" -> {GenericConversionService$ConvertersForPair@5400} "java.lang.String -> @org.springframework.format.annotation.DateTimeFormat java.time.ZonedDateTime: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.lang.String -> java.time.ZonedDateTime: org.springframework.format.datetime.standard.TemporalAccessorParser@68ae090e"
    {GenericConverter$ConvertiblePair@5401} "java.time.OffsetDateTime -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5402} "@org.springframework.format.annotation.DateTimeFormat java.time.OffsetDateTime -> java.lang.String: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.time.OffsetDateTime -> java.lang.String : org.springframework.format.datetime.standard.TemporalAccessorPrinter@3d68ac44"
    {GenericConverter$ConvertiblePair@5403} "java.lang.String -> java.time.OffsetDateTime" -> {GenericConversionService$ConvertersForPair@5404} "java.lang.String -> @org.springframework.format.annotation.DateTimeFormat java.time.OffsetDateTime: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.lang.String -> java.time.OffsetDateTime: org.springframework.format.datetime.standard.TemporalAccessorParser@854642c"
    {GenericConverter$ConvertiblePair@5405} "java.time.OffsetTime -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5406} "@org.springframework.format.annotation.DateTimeFormat java.time.OffsetTime -> java.lang.String: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.time.OffsetTime -> java.lang.String : org.springframework.format.datetime.standard.TemporalAccessorPrinter@15a8392c"
    {GenericConverter$ConvertiblePair@5407} "java.lang.String -> java.time.OffsetTime" -> {GenericConversionService$ConvertersForPair@5408} "java.lang.String -> @org.springframework.format.annotation.DateTimeFormat java.time.OffsetTime: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@648487da,java.lang.String -> java.time.OffsetTime: org.springframework.format.datetime.standard.TemporalAccessorParser@dd6b4ee"
    {GenericConverter$ConvertiblePair@5409} "java.time.Instant -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5410} "java.time.Instant -> java.lang.String : org.springframework.format.datetime.standard.InstantFormatter@7524339c"
    {GenericConverter$ConvertiblePair@5411} "java.lang.String -> java.time.Instant" -> {GenericConversionService$ConvertersForPair@5412} "java.lang.String -> java.time.Instant: org.springframework.format.datetime.standard.InstantFormatter@7524339c"
    {GenericConverter$ConvertiblePair@5413} "java.util.Calendar -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5414} "@org.springframework.format.annotation.DateTimeFormat java.util.Calendar -> java.lang.String: org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory@584ce5a1"
    {GenericConverter$ConvertiblePair@5415} "java.lang.String -> java.util.Calendar" -> {GenericConversionService$ConvertersForPair@5416} "java.lang.String -> @org.springframework.format.annotation.DateTimeFormat java.util.Calendar: org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory@584ce5a1"
    {GenericConverter$ConvertiblePair@5417} "java.util.Date -> java.lang.String" -> {GenericConversionService$ConvertersForPair@5418} "@org.springframework.format.annotation.DateTimeFormat java.util.Date -> java.lang.String: org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory@584ce5a1"
    {GenericConverter$ConvertiblePair@5419} "java.lang.String -> java.util.Date" -> {GenericConversionService$ConvertersForPair@5420} "java.lang.String -> @org.springframework.format.annotation.DateTimeFormat java.util.Date: org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory@584ce5a1"

      ③ WebDataBinder 核心类

      WebDataBinder:数据绑定器负责数据绑定工作,负责数据绑定期间产生的类型转换、格式化、数据校验等问题
        (1)ConversionService 组件进行数据类型转换、数据格式化工作;
        (2)Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象;
        (3)BindingResult 负责保存以及解析数据绑定期间数据校验产生的错误;
           Spring MVC 抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的响应入参;

      

    四、SpringMVC 的类型转换器

      ConversionService 组件:负责数据类型的转换以及格式化功能;
      ConversionService有非常多的 convert,不同类型的转换和格式化用它自己的 converter;

      Spring MVC 上下文中内建了很多转换器,可完成大多数 Java 类型的转换工作。

      以 StringToNumberConverterFactory 为例分析:

    {GenericConverter$ConvertiblePair@5229} "java.lang.String -> java.lang.Number" -> {GenericConversionService$ConvertersForPair@5230} "java.lang.String -> java.lang.Number : org.springframework.core.convert.support.StringToNumberConverterFactory@2d148610"
    

      

      查看:StringToNumberConverterFactory源码,在getConverter()方法中设置断点,在执行set方法(性别字段)前会调用该方法。

    final class StringToNumberConverterFactory implements ConverterFactory<String, Number> {
    
        @Override
        public <T extends Number> Converter<String, T> getConverter(Class<T> targetType) {
            return new StringToNumber<T>(targetType);
        }
    
        private static final class StringToNumber<T extends Number> implements Converter<String, T> {
    
            private final Class<T> targetType;
    
            public StringToNumber(Class<T> targetType) {
                this.targetType = targetType;
            }
    
            @Override
            public T convert(String source) {
                if (source.length() == 0) {
                    return null;
                }
                return NumberUtils.parseNumber(source, this.targetType);
            }
        }
    
    }

    五、@InitBinder 注解(了解)

      由 @InitBinder 标识的方法,可以对 WebDataBinder 对象进行初始化。WebDataBinder 是 DataBinder 的子类,用于完成由表单字段到 JavaBean 属性的绑定

      @InitBinder方法不能有返回值,它必须声明为void。

      @InitBinder方法的参数通常是 WebDataBinder。

      

       示例代码:

    /**
    由 @InitBinder 标识的方法,可以对 WebDataBinder 对象进行初始化。
    WebDataBinder 是 DataBinder 的子类,用于完成由表单字段到 JavaBean 属性的绑定
    @InitBinder方法不能有返回值,它必须声明为void。
    @InitBinder方法的参数通常是 WebDataBinder
     */
    @InitBinder
    public void initBinder(WebDataBinder dataBinder){
        dataBinder.setDisallowedFields("lastName");
    }
  • 相关阅读:
    java基础 01
    c++11——模板的细节改进
    c++11——auto,decltype类型推导
    poj_1182 并查集
    poj_1988 并查集
    poj_1161 并查集
    poj_3067 树状数组
    poj_2182 线段树/树状数组
    poj_1190 树状数组
    动态规划
  • 原文地址:https://www.cnblogs.com/niujifei/p/15627979.html
Copyright © 2011-2022 走看看