SpringMVC——数据转换 & 数据格式化 & 数据校验
一、数据绑定流程
- 1. Spring MVC 主框架将 ServletRequest 对象及目标方 法的入参实例传递给 WebDataBinderFactory 实例,以创 建 DataBinder 实例对象
- 2. DataBinder 调用装配在 Spring MVC 上下文中的 ConversionService 组件进行数据类型转换、数据格式 化工作。将 Servlet 中的请求信息填充到入参对象中
- 3. 调用 Validator 组件对已经绑定了请求消息的入参对象 进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象
- 4. Spring MVC 抽取 BindingResult 中的入参对象和校验 错误对象,将它们赋给处理方法的响应入参
Spring MVC 通过反射机制对目标处理方法进行解析,将请 求消息绑定到处理方法的入参中。数据绑定的核心部件是 DataBinder,运行机制如下:
源码分析
- 在JavaBean对象的属性setter方法处打断点调试
- 在调试页面进入org.springframework.web.method.annotation.ModelAttributeMethodProcessor#resolveArgument
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):this.createAttribute(name, parameter, binderFactory, request);
//创建binderd对象
WebDataBinder binder = binderFactory.createBinder(request, attribute, name);
if(binder.getTarget() != null) {
//数据的绑定
this.bindRequestParameters(binder, request);
//完成数据的校验
this.validateIfApplicable(binder, parameter);
if(binder.getBindingResult().hasErrors()
&& this.isBindExceptionRequired(binder, parameter)) {
throw new BindException(binder.getBindingResult());
}
} Map bindingResultModel = binder.getBindingResult().getModel();
mavContainer.removeAttributes(bindingResultModel);
mavContainer.addAllAttributes(bindingResultModel);
return binder.getTarget();
}
- 查看Binder对象的属性
- 可以看到binder包含了ConversionService和validators属性,它们分别处理类型转换和数据校验
二、数据转换
- Spring MVC 上下文中内建了很多转换器,可完成大多数 Java 类型的转换工作。
- ConversionService converters =
自定义类型转换器
ConversionService 是 Spring 类型转换体系的核心接口。
- 可以利用 ConversionServiceFactoryBean 在 Spring 的 IOC 容器中定义一个 ConversionService。Spring 将自动识别出 IOC 容器中的 ConversionService,并在 Bean 属性配置及 Spring MVC 处理方法入参绑定等场合使用它进行数据的转换
- 可通过 ConversionServiceFactoryBean 的 converters 属性 注册自定义的类型转换器
三、数据格式化
- 在表单添加birthday(生日)输入框,同时在Javabean中天机brith属性,属性的类型为Java.util.Date
- 提交表单时,页面报400错误,数据无法提交到目标方法
- 原因:输入框的birthday没有进行格式化
解决方法:
在Javabean对象的birth属性上加注解
@DateTimeFormat(pattern = "yy-mm-dd")
private Date birth;
①、日期格式化
@DateTimeFormat 注解可对 java.util.Date、java.util.Calendar、java.long.Long 时间 类型进行标注:
- pattern 属性:类型为字符串。指定解析/格式化字段数据的模式, 如:”yyyy-MM-dd hh:mm:ss”
- iso 属性:类型为 DateTimeFormat.ISO。指定解析/格式化字段数据 的ISO模式,包括四种:ISO.NONE(不使用) -- 默 认、ISO.DATE(yyyy-MM-dd) 、ISO.TIME(hh:mm:ss.SSSZ)、 ISO.DATE_TIME(yyyy-MM-dd hh:mm:ss.SSSZ)
- style 属性:字符串类型。通过样式指定日期时间的格式,由两位字 符组成,第一位表示日期的格式,第二位表示时间的格式:S:短日 期/时间格式、M:中日期/时间格式、L:长日期/时间格式、F:完整 日期/时间格式、-:忽略日期或时间格式
②、数值格式化
@NumberFormat 可对类似数字类型的属性进行标 注,它拥有两个互斥的属性:
- style:类型为 NumberFormat.Style。用于指定样式类 型,包括三种:Style.NUMBER(正常数字类型)、 Style.CURRENCY(货币类型)、 Style.PERCENT( 百分数类型)
- pattern:类型为 String,自定义样式, 如patter="#,###";
③、源码分析
- Spring MVC 上下文中内建了很多格式化处理器,可完成大多数 Java数据类型的格式化。
- ConversionService converters =
- 对属性对象的输入/输出进行格式化,从其本质上讲依然 属于 “类型转换” 的范畴。
- Spring 在格式化模块中定义了一个实现 ConversionService 接口的 FormattingConversionService 实现类,该实现类扩展 了 GenericConversionService,因此它既具有类型转换的功能,又具有格式化的功能
- FormattingConversionService 拥有一个 FormattingConversionServiceFactroyBean 工厂类, 后者用于在 Spring 上下文中构造前者
FormattingConversionServiceFactroyBean 内部已经注册了 :
- NumberFormatAnnotationFormatterFactroy:支持对数字类型的属性 使用 @NumberFormat 注解
- DateTimeFormatAnnotationFormatterFactroy:支持对日期类型 的属性使用 @DateTimeFormat 注解
- 装配了 FormattingConversionServiceFactroyBean 后,就可 以在 Spring MVC 入参绑定及模型数据输出时使用注解了。
- 默认创建的 ConversionService 实例即为 FormattingConversionServiceFactroyBean
④、自定义数据类型格式化&数据转换
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> <!-- 配置 ConversionService -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="自定义类型格式化&转换实现类"/>
</set>
</property>
</bean>
四、数据校验
JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架, 它已经包含在 JavaEE 6.0 中 .JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对 Bean 进行验证
Hibernate Validator 扩展注解:
- Hibernate Validator 是 JSR 303 的一个实现,除支持 所有标准的校验注解外,它还支持以下的扩展注解
校验流程
①. 使用 JSR 303 验证标准
②. 加入 hibernate validator 验证框架的 jar 包
hibernate-validator-5.0.0.CR2.jar
hibernate-validator-annotation-processor-5.0.0.CR2.jar
classmate-0.8.0.jar
jboss-logging-3.1.1.GA.jar
validation-api-1.1.0.CR1.jar
③. 在 SpringMVC 配置文件中添加 <mvc:annotation-driven />
④. 需要在 bean 的属性上添加对应的注解
package com.nchu.mybatis.bean; import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; /**
* Created by yangshijing on 2017/12/4 0004.
*/
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
private Integer deptId;
@DateTimeFormat(pattern = "yy-mm-dd")
private Date birth;
public Employee() {
} public Employee(String email, String gender, Integer id, String lastName,Integer deptId) {
this.email = email;
this.gender = gender;
this.id = id;
this.lastName = lastName;
this.deptId = deptId;
} public Date getBirth() {
return birth;
} public void setBirth(Date birth) {
this.birth = birth;
} public Integer getDeptId() {
return deptId;
} public void setDeptId(Integer deptId) {
this.deptId = deptId;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} public String getGender() {
return gender;
} public void setGender(String gender) {
this.gender = gender;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getLastName() {
return lastName;
} public void setLastName(String lastName) {
this.lastName = lastName;
} @Override
public String toString() {
return "Employee{" +
"id=" + id +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", gender='" + gender + '\'' +
",birth="+ birth +
'}';
}
}
⑤. 在目标方法 bean 类型的前面添加 @Valid 注解
/**
*添加employee接口
* @param employee
* @return
*/
@RequestMapping(value = "/emp" ,method= RequestMethod.POST)
public String save(@Valid Employee employee, Map<String,Object> map){
try{
employeeService.saveEmp(employee);
}catch (Exception e){
e.printStackTrace();
}
return "redirect:/employee/getemps";
}
⑥、表单email项未输入email格式时,无法访问到目标方法,并在控制台打印出错误信息
SpringMVC——数据转换 & 数据格式化 & 数据校验的更多相关文章
- SpringMVC 数据转换 & 数据格式化 & 数据校验
数据绑定流程 1. Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象 ...
- SpringMVC的数据转换&&数据格式化&&数据校验
1 SpringMVC的数据绑定流程 SpringMVC将ServletRequest对象及目标方法的入参实例传递给WebDataBinderFactory实例,以创建DataBinder实例对象. ...
- SpringMVC听课笔记(九:数据转换 & 数据格式化 & 数据校验)
1.数据绑定流程 --1). Spring MVC主框架将ServletRequest对象及目标方法入参实例传递给WebDataBinderFactory实例,以创建DataBinder实例对象. - ...
- Spring MVC @InitBinder 数据绑定 & 数据格式化 & 数据校验
1 数据绑定 2 数据格式化 修改绑定的字段等等操作 日期 - 接收表单日期字符串格式内容.,在实体类加入@DateTimeFormat 数值 原理: DefautFormattingConversi ...
- 项目中整合第三方插件与SpringMVC数据格式化关于ip地址
一.Bootstrap 响应式按钮 <div calss="col-sm-2"> <button class="btn btn-default btn- ...
- 10.SpringMVC之格式化、校验
数据格式化 数据格式化的注解: 数据校验JSR303 Hibernate Validator扩展注解 启动 springMVC数据校验 转换.格式化.校验出错处理:
- SpringMVC的数据转换,格式化和数据校验
在SpringMVC中,根据请求方法签名不同,将请求消息中的消息以一定的方式转换并绑定到请求方法的参数中,在请求信息到达真正调用处理方法的这一段时间内,SpringMVC还会完成很多其他的 ...
- SpringMVC——类型转换和格式化、数据校验、客户端显示错误消息
在介绍类型转换和格式化之前,我首先来介绍 <mvc:annotation-driven />. 需要导入的 schema: xmlns:mvc="http://www.sprin ...
- SpringMVC框架下数据的增删改查,数据类型转换,数据格式化,数据校验,错误输入的消息回显
在eclipse中javaEE环境下: 这儿并没有连接数据库,而是将数据存放在map集合中: 将各种架包导入lib下... web.xml文件配置为 <?xml version="1. ...
随机推荐
- [CF662C]Binary Table
luogu 题意 你有一个\(n*m\)的\(01\)矩阵.你可以把任意一行或者一列的\(01\)取反.求矩阵中最少的\(1\)的数量. \(n\le20,m\le10^5\) sol 很自然地有一个 ...
- Git克隆、修改、更新项目,及查看项目地址命令
第一步:在本地新建一个文件夹,作为本地仓库,如“texzt”,直接打开该文件夹,并单击右键,选择git bash here 则可以直接进入到该文件夹目录下. 第二步:将本地仓库初始化,命令:git i ...
- django的表与表之间的关系详细讲解
转:http://www.cnblogs.com/feixuelove1009/p/5855295.html
- 谷歌(google)世界各国网址大全
谷歌(google)世界各国网址大全世界各国google网址 国家 网址 国家主要语言 亚洲:中国 google.cn 汉语蒙古 google.mn蒙古语韩国 google.c ...
- maven编译问题:maven编译成功,eclipse文件未编译
我们先来看一个正常的编译流程: 1.从svn上检出一个项目: 2.看该工程是否为maven项目,不是则先转为maven项目:右键单击项目,选择configure->Convert to Mave ...
- Unidac手工安装
Universal Data Access Components Source Code Copyright 1997-2010, Devart. All Rights ReservedThere ...
- 找回mysql root用户的密码
1.停掉mysql服务ps -ef | grep mysqldkill -9 mysql进程的pid2.vi /etc/my.cnf找到[mysqld]在下面添加一行skip-grant-tables ...
- (转)winform下UPD通信的简单应用
本文转载自:http://blog.csdn.net/wanlong360599336/article/details/7557046 先看效果图: 使用UDP的好处就是不需要三次握手,但是缺点就是存 ...
- 比赛安排(穷举法或dfs)
比赛安排 时间限制: 1 Sec 内存限制: 125 MB提交: 11 解决: 10[提交][状态][讨论版][命题人:外部导入] 题目描述 设有2n(n<=6)个球队进行单循环比赛,计划在 ...
- 杂项-Java:JCP
ylbtech-杂项-Java:JCP JCP(Java Community Process) 是一个开放的国际组织,主要由Java开发者以及被授权者组成,职能是发展和更新. 1. 中文名:jcp 外 ...