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




springmvc中可以绑定集合数据的标签 简述springmvc数据绑定流程_mvc



  1. 数据类型转换
  • SpringMVC默认为我们装配了以下类型转换器:
  • 如果SpringMVC默认的类型转换器不能满足我们的需求,我们可以自定义类型转换器,如:将一个字符串转换为Employee对象
  • 创建一个类实现Converter<S,T>接口
public    class MyConverter 
  implements
  

      //  
  Tom-tom@atguigu.com-1-101 这种格式的写法转换  
  
@Override
  
public Employee convert(String    arg0) { 
 
  
employee  =    null; 
 
  
if(   arg0 != 
  null){ 
 
  
split =    arg0.split( 
  "-"); 
 
  
if(   split != 
  null && 
   split. 
  length
  
//获取姓名
  
lastName =   split[0]; 
 
  
//获取邮箱
  
email =    split[1]; 
 
  
//获取性别
  
int    gender = Integer.parseInt( 
  split[2]); 
 
  
//获取部门的id
  
int    deptId = Integer.parseInt( 
  split[3]); 
 
  
//创建Employee对象
  
employee  =    new
  
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) { 
 
  
// 保存该员工
  
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
  
//证明有错误信息
  
fieldErrors =   result.getFieldErrors(); 
 
  
for (FieldError    fieldError : 
  fieldErrors) { 
 
  
//获取出现异常的属性
  
field =    fieldError.getField(); 
 
  
//获取异常信息
  
message =    fieldError.getDefaultMessage(); 
 
  
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)
\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A
  
\u90AE\u7BB1\u683C\u5F0F\u4E0D\u6B63\u786E
  
\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