原文地址:http://www.cnblogs.com/linyueshan/p/5908490.html

数据绑定流程

1. Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象
2. DataBinder 调用装配在 Spring MVC 上下文中的 ConversionService 组件进行数据类型转换、数据格式化工作。将 Servlet 中的请求信息填充到入参对象中
3. 调用 Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象
4. Spring MVC 抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的响应入参

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

数据转换

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

自定义类型转换器

ConversionService 是 Spring 类型转换体系的核心接口。

可以利用 ConversionServiceFactoryBean 在 Spring 的 IOC 容器中定义一个 ConversionService. Spring 将自动识别出IOC 容器中的 ConversionService,并在 Bean 属性配置及
Spring MVC 处理方法入参绑定等场合使用它进行数据的转换
可通过 ConversionServiceFactoryBean 的 converters 属性注册自定义的类型转换器

<mvc:annotation-driven conversion-service="conversionService"/> 会将自定义的 ConversionService 注册到Spring MVC 的上下文中

  1. <mvc:annotation-driven
    conversion-service="conversionService"></mvc:annotation-driven>
  2.  
  3. <!-- 配置 ConversionService -->
  4. <bean
    id="conversionService"
  5.     class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
  6.     <property
    name="converters">
  7.         <set>
  8.             <ref
    bean="employeeConverter"/>
  9.         </set>
  10.     </property>

  11. </bean>

Spring 支持的转换器

Spring 定义了 3 种类型的转换器接口,实现任意一个转换器接口都可以作为自定义转换器注册到ConversionServiceFactroyBean 中:
Converter<S,T>:将 S 类型对象转为 T 类型对象 
ConverterFactory:将相同系列多个 "同质" Converter 封装在一起。如果希望将一种类型的对象转换为另一种类型及其子类的对象(例如将 String 转换为 Number 及 Number 子类(Integer、Long、Double 等)对象)可使用该转换器工厂类
GenericConverter:会根据源类对象及目标类对象所在的宿主类中的上下文信息进行类型转换

  1. @Component
  2. public
    class EmployeeConverter implements Converter<String, Employee> {
  3.  
  4.     @Override
  5.     public Employee convert(String source) {
  6.         if(source != null){
  7.             String [] vals = source.split("-");
  8.             //GG-gg@atguigu.com-0-105
  9.             if(vals != null && vals.length == 4){
  10.                 String lastName = vals[0];
  11.                 String email = vals[1];
  12.                 Integer gender = Integer.parseInt(vals[2]);
  13.                 Department department = new Department();
  14.                 department.setId(Integer.parseInt(vals[3]));
  15.  
  16.                 Employee employee = new Employee(null, lastName, email, gender, department);
  17.                 System.out.println(source + "--convert--" + employee);
  18.                 return employee;
  19.             }
  20.         }
  21.         return
    null;
  22.     }
  23.  
  24. }

关于 mvc:annotation-driven

<mvc:annotation-driven /> 会自动注册 RequestMappingHandlerMapping、RequestMappingHandlerAdapter 与ExceptionHandlerExceptionResolver 三个bean。
还将提供以下支持: 
  支持使用 ConversionService 实例对表单参数进行类型转换 
  支持使用 @NumberFormat annotation、@DateTimeFormat 注解完成数据类型的格式化
  支持使用 @Valid 注解对 JavaBean 实例进行 JSR 303 验证 
  支持使用 @RequestBody 和 @ResponseBody 注解

@InitBinder

由 @InitBinder 标识的方法,可以对 WebDataBinder 对象进行初始化。WebDataBinder 是 DataBinder 的子类,用于完成由表单字段到 JavaBean 属性的绑定
@InitBinder方法不能有返回值,它必须声明为void。
@InitBinder方法的参数通常是是 WebDataBinder

数据格式化

对属性对象的输入/输出进行格式化,从其本质上讲依然属于 "类型转换" 的范畴。
Spring 在格式化模块中定义了一个实现 ConversionService 接口的FormattingConversionService 实现类,该实现类扩展了 GenericConversionService,因此它既具有类型转换的
功能,又具有格式化的功能
FormattingConversionService 拥有一个FormattingConversionServiceFactroyBean 工厂类,后者用于在 Spring 上下文中构造前者

FormattingConversionServiceFactroyBean 内部已经注册了 :
  NumberFormatAnnotationFormatterFactroy:支持对数字类型的属性使用 @NumberFormat 注解
  JodaDateTimeFormatAnnotationFormatterFactroy:支持对日期类型的属性使用 @DateTimeFormat 注解
装配了 FormattingConversionServiceFactroyBean 后,就可以在 Spring MVC 入参绑定及模型数据输出时使用注解驱动了。<mvc:annotation-driven/> 默认创建的
ConversionService 实例即为FormattingConversionServiceFactroyBean.

日期格式化

@DateTimeFormat 注解可对java.util.Date、java.util.Calendar、java.long.Long 时间类型进行标注:

1

2

3

@Past

@DateTimeFormat(pattern="yyyy-MM-dd")

private Date birth;

 数值格式化

@NumberFormat • 可对类似数字类型的属性进行标注,它拥有两个互斥的属性:
style:类型为 NumberFormat.Style。用于指定样式类型,包括三种:Style.NUMBER(正常数字类型)、Style.CURRENCY(货币类型)、 Style.PERCENT(百分数类型)
pattern:类型为 String,自定义样式,如patter="#,###";

1

2

@NumberFormat(pattern="#,###,###.#")

private Float salary;

 数据校验

JSR 303

JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 中 .
JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对 Bean 进行验证

Constraint

详细信息

@Null

被注释的元素必须为 null

@NotNull

被注释的元素必须不为 null

@AssertTrue

被注释的元素必须为 true

@AssertFalse

被注释的元素必须为 false

@Min(value)

被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@Max(value)

被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@DecimalMin(value)

被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@DecimalMax(value)

被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@Size(max, min)

被注释的元素的大小必须在指定的范围内

@Digits (integer, fraction)

被注释的元素必须是一个数字,其值必须在可接受的范围内

@Past

被注释的元素必须是一个过去的日期

@Future

被注释的元素必须是一个将来的日期

@Pattern(value)

被注释的元素必须符合指定的正则表达式

Hibernate Validator 扩展注解

Hibernate Validator 是 JSR 303 的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解

表 2. Hibernate Validator 附加的 constraint

Constraint

详细信息

@Email

被注释的元素必须是电子邮箱地址

@Length

被注释的字符串的大小必须在指定的范围内

@NotEmpty

被注释的字符串的必须非空

@Range

被注释的元素必须在合适的范围内

Spring MVC 数据校验

Spring 4.0 拥有自己独立的数据校验框架,同时支持 JSR 303 标准的校验框架。
Spring 在进行数据绑定时,可同时调用校验框架完成数据校验工作。在 Spring MVC 中,可直接通过注解驱动的方式进行数据校验
Spring 的 LocalValidatorFactroyBean 既实现了 Spring 的Validator 接口,也实现了 JSR 303 的 Validator 接口。只要在 Spring 容器中定义了一个LocalValidatorFactoryBean,即可将其注入到需要数据校验的 Bean 中。
Spring 本身并没有提供 JSR303 的实现,所以必须将JSR303 的实现者的 jar 包放到类路径下。

<mvc:annotation-driven/> 会默认装配好一个 LocalValidatorFactoryBean,通过在处理方法的入参上标注 @valid 注解即可让 Spring MVC 在完成数据绑定后执行数据校验的工作

如何校验 ? 注解 ?
            ①. 使用 JSR 303 验证标准
            ②. 加入 hibernate validator 验证框架的 jar 包
            ③. 在 SpringMVC 配置文件中添加 <mvc:annotation-driven />
            ④. 需要在 bean 的属性上添加对应的注解
            ⑤. 在目标方法 bean 类型的前面添加 @Valid 注解

  1. public
    class Order {
  2.  // 必须不为 null, 大小是 10
  3.  @NotNull
  4.  @Size(min = 10, max = 10)
  5.  private String orderId;
  6.  // 必须不为空
  7.  @NotEmpty
  8.  private String customer;
  9.  // 必须是一个电子信箱地址
  10.  @Email
  11.  private String email;
  12.  // 必须不为空
  13.  @NotEmpty
  14.  private String address;
  15.  // 必须不为 null, 必须是下面四个字符串'created', 'paid', 'shipped', 'closed'其中之一
  16.  // @Status 是一个定制化的 contraint
  17.  @NotNull
  18.  @Status
  19.  private String status;
  20.  // 必须不为 null
  21.  @NotNull
  22.  private Date createDate;
  23.  // 嵌套验证
  24.  @Valid
  25.  private Product product;
  26.  
  27.  getter 和 setter
  28.  }

注意:需校验的 Bean 对象和其绑定结果对象或错误对象时成对出现的,它们之间不允许声明其他的入参

  1. @RequestMapping(value="/emp", method=RequestMethod.POST)
  2.     public String save(@Valid Employee employee, Errors result,
  3.             Map<String, Object> map){
  4.         System.out.println("save: " + employee);
  5.  
  6.         if(result.getErrorCount() > 0){
  7.             System.out.println("出错了!");
  8.  
  9.             for(FieldError error:result.getFieldErrors()){
  10.                 System.out.println(error.getField() + ":" + error.getDefaultMessage());
  11.             }
  12.  
  13.             //若验证出错, 则转向定制的页面
  14.             map.put("departments", departmentDao.getDepartments());
  15.             return "input";
  16.         }
  17.  
  18.         employeeDao.save(employee);
  19.         return "redirect:/emps";
  20.     }

 在页面上显示错误

Spring MVC 除了会将表单/命令对象的校验结果保存到对应的 BindingResult 或 Errors 对象中外,还会将所有校验结果保存到 "隐含模型"

隐含模型中的所有数据最终将通过 HttpServletRequest 的属性列表暴露给 JSP 视图对象,因此在 JSP 中可以获取错误信息
在 JSP 页面上可通过 <form:errors path="userName"> 显示错误消息

  1. Birth: <form:input
    path="birth"/>
  2. <form:errors
    path="birth"></form:errors>

若数据类型转换或数据格式转换时发生错误,或该有的参数不存在,或调用处理方法时发生错误,都会在隐含模型中创建错误消息。其错误代码前缀说明如下:
  required:必要的参数不存在。如 @RequiredParam("param1") 标注了一个入参,但是该参数不存在
  typeMismatch:在数据绑定时,发生数据类型不匹配的问题 –
  methodInvocation:Spring MVC 在调用处理方法时发生了错误

Spring mvc数据转换 格式化 校验(转载)的更多相关文章

  1. Spring MVC 数据转换和格式化

    HttpMessageConverter和JSON消息转换器 HttpMessageConverter是定义从HTTP接受请求信息和应答给用户的 HttpMessageConverter是一个比较广的 ...

  2. 【Spring学习笔记-MVC-10】Spring MVC之数据校验

    作者:ssslinppp       1.准备 这里我们采用Hibernate-validator来进行验证,Hibernate-validator实现了JSR-303验证框架支持注解风格的验证.首先 ...

  3. spring mvc 4数据校验 validator

    注解式控制器的数据验证.类型转换及格式化——跟着开涛学SpringMVC http://jinnianshilongnian.iteye.com/blog/1733708Spring4新特性——集成B ...

  4. Spring MVC数据转换

    样例:把一个字符串封装而一个对象. 如:username:password格式的数据ZhangSan:1234.我们把这个数据封装成一个User对象.以下分别使用属性编辑器与转换器来实现. 1.自己定 ...

  5. Spring MVC 表单校验 (七)

    完整的项目案例: springmvc.zip 目录 实例 除了依赖spring-webmvc还需要依赖jackson-databind(用于转换json数据格式)和hibernate-validato ...

  6. spring mvc 数据格式化

    web.xml <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www. ...

  7. spring mvc 数据转换

    项目目录结构 User.java package org.mythsky.springmvcdemo.model; import org.springframework.format.annotati ...

  8. Spring MVC 数据校验@Valid

    先看看几个关键词 @Valid @Pattern @NotNull @NotBlank @Size BindingResult 这些就是Spring MVC的数据校验的几个注解. 那怎么用呢?往下看 ...

  9. Spring MVC 与 web开发

    转载:http://coderbee.net/index.php/java/20140719/959 项目组用了 Spring MVC 进行开发,觉得对里面的使用方式不是很满意,就想,如果是我来搭建开 ...

随机推荐

  1. OPCDAAuto的一个坑

    最近项目需要对SCADA系统的下位机采集实时数据,常见做法是两种,一种采用ModBus RTU/TCP协议直接通过支持ModBus的下位机通信,一种是通过OPC规范,使用厂商提供的OPC Server ...

  2. web开发(二) Servlet中response、request乱码问题解决

    在网上看见一篇不错的文章,写的详细. 以下内容引用那篇博文.转载于<http://www.cnblogs.com/whgk/p/6412475.html>,在此仅供学习参考之用. 一.re ...

  3. [Cinder] 存储 Qos

    目录 文章目录 目录 前言 操作步骤 参考文章 前言 Cinder 支持 front-end 和 back-end 两种类型的存储 QoS,前者由 Hypervisor 端实现(e.g. 通过 Lib ...

  4. Selenium 2自动化测试实战14(定位一组元素)

    一.定位一组元素 WebDriver还提供了与前面所对应的8钟用于定位一组元素的方法.定位一组元素的方法与定位单个元素的方法类似,唯一的区别是在单词element后面多了一个S表示复数.定位一组元素一 ...

  5. Selenium 2自动化测试实战12(获得验证信息)

    一.获得验证信息 通常用的最多的几种验证信息分别是:title.URL和text 运行脚本之后,结果如下图所示: #coding:utf-8 from selenium import webdrive ...

  6. vim技巧1

    在编辑模式或可视模式下输入的命令会另外注明.1. 查找   /xxx(?xxx)       表示在整篇文档中搜索匹配xxx的字符串, / 表示向下查找, ? 表示                   ...

  7. Linux进程的虚拟内存

    简介 用户进程的虚拟地址空间是Linux的一个重要的抽象:它为每个运行进程提供了同样的系统视图,这使得多个进程可以同时运行,而不会干扰到其他进程内存中的内容. 每个应用程序都有自己的线性地址空间,与所 ...

  8. Jmeter安装篇(win10)

    参考博文:https://blog.csdn.net/a13124837937/article/details/79628838 以下是我按照参考博文进行的实际操作过程,此篇只为记录,尽量精简内容. ...

  9. cocos2dx基础篇(25) 简单碰撞检测

    [3.x] 将数学类 CCPoint.CCRect 改为v3.x版本的 Vec2.Rect 就好了. [简单碰撞检测] 在一些游戏中经常会遇到碰撞检测的情况,如愤怒的小鸟飞出去后,是否与石头发生碰撞. ...

  10. Linux系统管理和调优(内存、CPU、磁盘IO、网络)

    系统管理 Author:Rich七哥 查看 CPU 负载相关工具,找出系统中使用 CPU 最多的进程 查看 Memory 运行状态相关工具,找出系统中使用内存最多的进程 查看 IO 运行状态相关工具, ...