08.SpringMVC_数据绑定的流程

1.当我们提交表单,将表单中的数据绑定的方法的入参的对象中时,会涉及到数据绑定的流程,数据绑定的流程分为:数据类型转换、数据格式化、数据校验

  1. 数据类型转换
  • SpringMVC默认为我们装配了以下类型转换器:
  • 如果SpringMVC默认的类型转换器不能满足我们的需求,我们可以自定义类型转换器,如:将一个字符串转换为Employee对象
    • 创建一个类实现Converter<S,T>接口
public class MyConverter implements Converter<String, Employee> {
   //  Tom-tom@atguigu.com-1-101 这种格式的写法转换
     @Override
     public Employee convert(String arg0) {
         Employee employee  = null;
          if( arg0 != null){
             String[] split = arg0.split( "-");
              if( split != null && split. length == 4){
                  //获取姓名
                 String lastName = split[0];
                  //获取邮箱
                 String email = split[1];
                  //获取性别
                  int gender = Integer.parseInt( split[2]);
                  //获取部门的id
                  int deptId = Integer.parseInt( split[3]);
                  //创建Employee对象
                  employee  = new Employee();
                  employee.setLastName( lastName);
                  employee.setEmail( email);
                  employee.setGender( gender);
                  employee.setDepartment( new DepartmentDao().getDepartment( deptId));
             }
         }
          return employee;
    }
}
  • 在SpringMVC配置文件中配置自定义的类型转换器
  <!-- 配置类型转换器 -->
     < bean id= "conversionService" class= "org.springframework.context.support.ConversionServiceFactoryBean" >
         < property name= "converters" >
              < set >
                  < bean class= "com.atguigu.springmvc.converter.MyConverter" ></ bean >
              </ set >
         </ property >
     </ bean >
     < mvc:annotation-driven conversion-service= "conversionService" ></ mvc:annotation-driven >
这个必须写在 < mvc:annotation-driven ></ mvc:annotation-driven >之前才行
// 测试自定义转换器
     @RequestMapping(value = "/testMyConverter", method = RequestMethod. POST)
     public String testMyConverter( @RequestParam( "employee") Employee employee) {
        // 保存该员工
       System. out.println( employee);
        employeeDao.save( employee);
        return "redirect:/getEmployees";
    
  • 备注:
   在Handler中通过 @InitBinder这个标签在数据绑定的过程不允许给某一个属性赋值
 @InitBinder
    public void initGender(WebDataBinder dataBinder){
        //数据绑定的过程不允许给性别赋值
        dataBinder.setDisallowedFields("gender");
    }
  • @InitBinder方法不能有返回值,它必须声明为void。
  • @InitBinder方法的参数通常是 WebDataBinder

  • 备注:
<mvc:annotation-driven/>配置在什么时候必须配置?
  1. 直接配置响应的页面:无需经过控制器来执行结果 ;但会导致其他请求路径失效,需要配置mvc:annotation-driven标签<mvc:view-controller path="/success" view-name="success"/>
  2. 通过jQuery执行delete请求时,找不到静态资源,需要配置mvc:annotation-driven标签   
  3. 配置类型转换器服务时,需要指定转换器服务引用<mvc:annotation-driven conversion-service=“conversionService”/> 会将自定义的ConversionService 注册到 Spring MVC 的上下文中
  4. 数据验证,也需要配置 
3.数据的格式化
  • 我们可以通过@DateTimeFormat和@NumberFormat注解对应日期和数据进行格式化,只需要在要格式化的类的属性上添加以上注解即可
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private Date birthday;
     @NumberFormat(pattern= "#,###,###.##")
     private double salary;
  • 要使@DateTimeFormat和@NumberFormat注解起作用,必须配置<mvc:annotation-driven></mvc:annotation-driven>
< mvc:annotation-driven ></ mvc:annotation-driven >
配置,配置时不能指定conversion-service属性 ,否则,依然报错 400 。要把 <mvc:annotation-driven conversion-service="conversionService"/>注掉才行
备注:
FormattingConversionService 实现类, 既具有类型转换的功能,又具有格式化的功能
  • <mvc:annotation-driven/> 默认创建的 ConversionService 实例即为
  DefaultFormattingConversionService
4.数据校验
  • 我们可以通过Hibernate Validator进行数据校验,使用它需要到导入以下jar包
    classmate-0.8.0.jar
    hibernate-validator-5.0.0.CR2.jar
    hibernate-validator-annotation-processor-5.0.0.CR2.jar
    jboss-logging-3.1.1.GA.jar
    validation-api-1.1.0.CR1.jar
  • 然后在要校验的属性上添加对应的注解
     @NotEmpty
     private String lastName;
    
     @Email
     private String email;
    
     @Past
     private Date birthday;
  • 在要校验的属性对应的对象的前面添加@Valid注解,同时紧挨着该对象传入BindingResult类型的入参,通过它获取异常信息
// 添加新员工
     @RequestMapping(value = "/emp", method = RequestMethod. POST)
     public String addEmployee( @Valid Employee employee , BindingResult result) {
          // BindingResult结果集对象必须紧挨着被校验的employee对象,中间不能有其他参数
//       System.out.println(employee);
          int errorCount = result.getErrorCount();
          if( errorCount > 0){
              //证明有错误信息
             List<FieldError> fieldErrors = result.getFieldErrors();
              for (FieldError fieldError : fieldErrors) {
                  //获取出现异常的属性
                 String field = fieldError.getField();
                  //获取异常信息
                 String message = fieldError.getDefaultMessage();
                 System. out.println( field+ ":"+ message);
             }
              //转发到输入用户信息的页面
              return "input";
         }
          // 保存用户
          employeeDao.save( employee);
          return "redirect:/emps";
    }
  • 要想当校验的注解起作用,必须配置<mvc:annotation-driven></mvc:annotation-driven>
< mvc:annotation-driven ></ mvc:annotation-driven >
  • 通过<form:errors></form:errors>表单在前端页面显示错误信息
  <!-- SpringMVC提供的表单默认表单中的数据是必须要回显的,默认情况下,SpringMVC会以command 作为key从request域中
          查询模型数据,然后回显,找不到则会抛出异常。我们可以通过form表单的modelAttribute属性来指定在request域中放的模型数据的key
      -->
     < form:form modelAttribute= "employee" >
          <!-- 如果path的值为通配符*,将显示所有的错误信息,如果要显示对应的错误信息,将该值设置为属性名即可-->
<%--          <form:errors path="*"> </form:errors> --%>
         <!-- path属性就相当于input中的name属性 -->
          <!-- 当员工的id为null,即在添加新员工时再显示姓名 -->   
          < c:if test= "${ empty requestScope.employee.id } " >   
             姓名: < form:input path= "lastName" /> < form:errors path= "lastName" ></ form:errors > < br >
          </ c:if > 
         <!-- 对应更新来说,需要将POST请求转换为PUT请求,所以需要传一个请求参数_method --> 
         < c:if test= "${! empty requestScope.employee.id } " >
              < form:hidden path= "id" />
              < input type= "hidden" name= "_method" value= "put" >
         </ c:if >
        邮箱: < form:input path= "email" /> < form:errors path= "email" ></ form:errors > < br >
        性别: < form:radiobutton path= "gender" value= "1" label= "男" />
              < form:radiobutton path= "gender" value= "0" label= "女" />< br >
        部门: < form:select path= "department.id" items= "${requestScope.depts } " itemValue= "id" itemLabel= "departmentName" ></ form:select >
              < br >
        生日: < form:input path= "birthday" /> < form:errors path= "birthday" ></ form:errors > < br >
        期望薪资: < form:input path= "salary" />< br >
              < input type= "submit" >
     </ form:form >
  • 国际化错误信息
    • 在SpringMVC的配置文件中配置国际化资源文件
<!-- 配置国际化资源文件 -->
     < bean id= "messageSource" class= "org.springframework.context.support.ResourceBundleMessageSource" >
         < property name= "basename" value= "i18n" ></ property >
     </ bean >
  • 国际化资源文件(i18n_zh_CN.properties)
NotEmpty.employee.lastName= \u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A
Email.employee.email= \u90AE\u7BB1\u683C\u5F0F\u4E0D\u6B63\u786E
Past.employee.birthday= \u4EB2\u7231\u7684\uFF0C\u4F60\u51FA\u751F\u7684\u65F6\u95F4\u8FD8\u6CA1\u5230\uFF0C\u5728\u4F60\u5988\u5988\u809A\u5B50\u91CC\u518D\u5446\u4E9B\u65F6\u65E5\u5427\uFF01\uFF01\uFF01



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值