• Spring MVC-学习笔记(4)数据绑定流程


    1、请求数据在到达处理方法前这段时间。

        spring MVC还会做请求信息转换、数据转换、数据格式化、数据校验。

    2、数据转换

      1》ConversionService:

         Spring类型转换体系的核心接口,在其中定义了一下4个方法:

           

       可以在spring上下文中注册一个ConversionServiceFactoryBean,用以定义一个ConversionService。spring上下文将识别出这个ConversionService,并在spring mvc处理方法的参数绑定中使用它进行数据转换。

       在ConversionServiceFactoryBean中可以内置很多的类型转换器,使用它们可以完成大多数Java类型的转换工作。其除了包括将spring对象转换为各种基础类型的对象外,还包括String、Number、Array、Collection、Map、Properties及Object之间的转换器。可以通过ConversionServiceFactoryBean的converters属性注册自定义的类型转换器。

    <bean id="conversionService"
          class="org.springframework.context.support.ConversionServiceFactoryBean">
       <property name="converters">
             <list>
                  <bean class="com.lfy.converter.StringToDateConverter"/>
             </list>
       </property>
    </bean>

       2》spring支持的转换器

          spring在org.springframework.core.convert.concerter包中定义了3种类型的转换器接口,我们可以实现其中任意一种转换器接口,并将它作为自定义转换器注册到ConversionServiceFactoryBean当中。3种转换器接口:

        

        举个例子:

        假设某User类型的组成如下,User还作为处理方法的参数。前端页面传递的都是字符串类型。

    public class User implements Serializable{
        
        private static final long serialVersionUID = 1L;
        
        private String loginname;
        private Date birthday;
            ...
    }

        这时候接收Date类型的数据绑定到User中就要经过处理了,开发自己的转换器StringToDateConverter.java。

    import java.text.SimpleDateFormat;
    import java.util.Date;
    import org.springframework.core.convert.converter.Converter;
    
    // 实现Converter<S,T>接口
    public class StringToDateConverter implements Converter<String, Date>{
    
        // 日期类型模板:如yyyy-MM-dd
        private String datePattern;
        
        public void setDatePattern(String datePattern) {
            this.datePattern = datePattern;
        }
    
        // Converter<S,T>接口的类型转换方法
        @Override
        public Date convert(String date) {
            try {
                SimpleDateFormat dateFormat = new SimpleDateFormat(this.datePattern);
                // 将日期字符串转换成Date类型返回
                return dateFormat.parse(date);
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("日期转换失败!");
                return null;
            }
        }
    }

       在springmvc-config.xml中加入自定义的字符转换器。

        <!-- 装配自定义的类型转换器,
    默认annotation-dricen会注册一个ConversionService,即FormattingConversionServiceFactoryBean
    ,以满足大多数类型转换的需求。现在要注册一个自定义的转换类,因此需要显式地使用一个ConversionService覆盖
    默认的实现类,通过制定conversion-service指定。这样在任意处理器中都可以使用该转换器了。
    --> <mvc:annotation-driven conversion-service="conversionService"/> <!-- 自定义的类型转换器 --> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.lfy.converter.StringToDateConverter" p:datePattern="yyyy-MM-dd"/> </list> </property> </bean>

       UserController.java

    package com.lfy.controller;
    
    import com.lfy.bean.User;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class UserController{
         
        ...
        @RequestMapping(value="/register")
         public String register(
                 @ModelAttribute User user,
                 Model model) {
             System.out.println(user);
             model.addAttribute("user", user);
             return "success";
         }
    }

       运行结果:

       

       

       3》使用@InitBinder添加自定义的编辑器转换数据

         spring MVC在支持新的转换器框架的同时,也支持Java Bean的PropertyEditor。可以在控制器中使用@InitBinder添加自定义的编辑器。

         在上面一个例子中将springmvc-config.xml中自定义的转换器删除。然后添加DateEditor.java

    package com.lfy.converter;
    
    import java.beans.PropertyEditorSupport;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class DateEditor extends PropertyEditorSupport {
    
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date date = dateFormat.parse(text);
                setValue(date);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

       修改UserController.java

    package com.lfy.controller;
    
    import com.lfy.bean.User;
    import com.lfy.converter.DateEditor;
    
    import java.util.Date;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.WebDataBinder;
    import org.springframework.web.bind.annotation.InitBinder;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class UserController{
         
        @RequestMapping(value="/registerForm")
         public String registerForm(){
            return "registerForm";
        }
        
        // 在控制器初始化时注册属性编辑器
        @InitBinder
        public void initBinder(WebDataBinder binder){
           // 注册自定义编辑器
           binder.registerCustomEditor(Date.class, new DateEditor());
        }
         
        @RequestMapping(value="/register")
         public String register(
                 @ModelAttribute User user,
                 Model model) {
             System.out.println(user);
             model.addAttribute("user", user);
             return "success";
         }
    }

       运行,结果和上面的例子一致。

      4》使用WebBindingInitializer注册全局自定义编辑器转换数据

        如果希望在全局范围内使用自定义的编辑器,则可以通过实现WebBindingInitializer接口并在该实现类中注册自定义编辑器完成。

        增加DateBindingInitializer.java

    package com.lfy.binding;
    
    import java.util.Date;
    import com.lfy.converter.DateEditor;
    import org.springframework.web.bind.WebDataBinder;
    import org.springframework.web.bind.support.WebBindingInitializer;
    import org.springframework.web.context.request.WebRequest;
    
    public class DateBindingInitializer implements WebBindingInitializer {
    
        @Override
        public void initBinder(WebDataBinder binder, WebRequest webRequest) {
            binder.registerCustomEditor(Date.class, new DateEditor());
        }
    
    }

        去除UserController.java中的@InitBinder注解,UserController.java

    package com.lfy.controller;
    
    import com.lfy.bean.User;
    import com.lfy.converter.DateEditor;
    
    import java.util.Date;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.WebDataBinder;
    import org.springframework.web.bind.annotation.InitBinder;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class UserController{
         
        @RequestMapping(value="/registerForm")
         public String registerForm(){
            return "registerForm";
        }
         
        @RequestMapping(value="/register")
         public String register(
                 @ModelAttribute User user,
                 Model model) {
             System.out.println(user);
             model.addAttribute("user", user);
             return "success";
         }
    }

       修改springmvc-config.xml,配置全局的自定义编辑器

    <?xml version="1.0" encoding="utf-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns="http://www.springframework.org/schema/beans"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="
           http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
           http://www.springframework.org/schema/context 
           http://www.springframework.org/schema/context/spring-context.xsd 
           http://www.springframework.org/schema/mvc 
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">
           
          <mvc:default-servlet-handler/>
          
          <!-- 扫描controller -->
          <context:component-scan base-package="com.lfy.controller"/>

            <!-- 通过RequestMappingHandlerAdapter装配自定义编辑器 -->
            <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
                <property name="webBindingInitializer">
                   <bean  class="com.lfy.binding.DateBindingInitializer" />
                </property>
            </bean>

          <!-- 视图解析器 -->
          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
                p:prefix="/WEB-INF/content/" p:suffix=".jsp" />
    </beans>

       运行,结果与上一示例一致。

    3、多种转换器的优先级(多种方式可以同时并存),优先查找顺序为:

       

    4、数据格式化

    5、数据校验

  • 相关阅读:
    酒店预定系统
    毕业论文管理系统 ——总体设计
    毕业论文管理系统
    毕业管理系统——面向对象方法 项目前期
    项目前期
    5/23用户故事和backlog
    5/18
    4.8
    4.3
    第四章 需求分析
  • 原文地址:https://www.cnblogs.com/ZeroMZ/p/11424794.html
Copyright © 2020-2023  润新知