SpringMVC的数据转换&&数据格式化&&数据校验
1 SpringMVC的数据绑定流程
- SpringMVC将ServletRequest对象及目标方法的入参实例传递给WebDataBinderFactory实例,以创建DataBinder实例对象。
- DataBinder调用装配在SpringMVC上下文中ConversionService组件进行数据类型转换、数据格式化工作。将Servlet中的请求信息填充到入参对象中。
- 调用Validator组件对已经绑定了请求信息的入参对象进行数据合法性校验,并最终生成数据绑定结果BindingData对象。
- SpringMVC抽取BindingResult中的入参对象和校验错误对象,将它们赋给处理方法的响应入参。
- SpringMVC通过反射机制对目标处理方法进行解析,将请求消息绑定到处理方法的入参中。数据绑定的核心部件是DataBinder,运行机制如下:

2 数据转换
- SpringMVC上下文中内建了很多转换器,可以完成大多数Java类型的转换工作。
2.1 自定义类型转换器
- ConversionService是Spring类型转换体系的核心接口。
- 可以利用ConversionServiceFactoryBean在Spring的IOC容器中定义一个ConversionService。Spring将自动识别出IOC容器中的ConversionService,并在Bean属性配置及SpringMVC处理方法入参绑定等场合使用它进行数据的转换。
- 可以通过ConversionServiceFactoryBean的converters属性注册自定义的类型转换器。
- 示例:
- index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body> <a href="${pageContext.request.contextPath}/test?user=adc,123456,1">增加数据</a> </body>
</html>
- User.java
package com.sunxiaping.springmvc.domain;
import java.io.Serializable;
public class User implements Serializable {
private String username;
private String password;
private Integer age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
- UserConverter.java
package com.sunxiaping.springmvc.converters; import com.sunxiaping.springmvc.domain.User;
import org.springframework.core.convert.converter.Converter; public class UserConverter implements Converter<String, User> {
@Override
public User convert(String s) {
if (null == s || s.length() == 0) {
return null;
}
String[] split = s.split(","); User user = new User();
user.setUsername(split[0]);
user.setPassword(split[1]);
user.setAge(Integer.parseInt(split[2])); return user;
}
}
- UserController.java
package com.sunxiaping.springmvc.controller; import com.sunxiaping.springmvc.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class UserController { @RequestMapping(value = "/test")
public String test(User user){ System.out.println(user); return "success";
} }
- SpringMVC.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd "> <!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.sunxiaping.springmvc"></context:component-scan> <!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.sunxiaping.springmvc.converters.UserConverter"></bean>
</set>
</property>
</bean> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> </beans>
- success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
成功啦 <br/> </body>
</html>
2.2 关于<mvc:annotation-drivern>
- <mvc:annotation-drivern>会自动注册RequestMappingHandlerMapping、RequestMappingHandlerAdapter和ExceptionHandlerExceptionResolver三个Bean。
- 还将提供以下的支持:
- 支持使用ConversionService实例对表单参数进行转换。
- 支持使用@NumberFormat注解和@DateTimeFormat注解完成数据格式化。
- 支持使用@Valid注解对JavaBean实例进行JSR303验证。
- 支持使用@RequestBody和@Res婆娘色Body注解。
2.3 @InitBinder注解
- 由@InitBinder标识的方法,可以对WebDataBinder对象进行初始化。WebDataBinder是DataBinder的子类,用于完成由表单字段到JavaBean属性的绑定。
- @InitBinder方法不能由返回值,它必须声明为void。
- @InitBinder方法的参数通过是WebDataBinder。
- 示例:
@InitBinder
public void initBinder(WebDataBinder webDataBinder){
webDataBinder.setDisallowedFields("roleIds");
}
3 数据格式化
- 对属性对象的输入/输出进行格式化,从其本质上讲依然是属于”类型转换“的范畴。
- Spring在格式化模块中定义了一个实现ConversionService接口的FormattingConversionService的实现类,该实现类扩展了GenericConversionService,因此它既具有类型转换的功能,又具有格式化的功能。
- FormattingConversionService拥有一个FormattingConversionServiceFactoryBean工厂类,后者用于在Spring上下文中构造前者。
- FormattingConversionServiceFactoryBean内部注册了:
- NumberFormatAnnotationFormatterFactory:支持对数字的属性使用@NumberFormat注解。
- JodaDateTimeFormatAnnotationFormatterFactory:支持对日期类型的属性使用@DateTimeFormat注解。
- 装配了FormattingConversionServiceFactoryBean后,就可以在SpringMVC入参绑定及模型数据输出的时候使用注解驱动了。
- <mvc:annotation-drivern/>默认创建的ConverionService实例就是FormattingConversionServiceFactoryBean。
3.1 日期格式化
- @DateTimeFormat注解可以为java.util.Date、java.util.Calendar、java.lang.Long时间类型进行标注。
package org.springframework.format.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
public @interface DateTimeFormat { String style() default "SS"; ISO iso() default ISO.NONE; String pattern() default ""; enum ISO { /**
* The most common ISO Date Format {@code yyyy-MM-dd},
* e.g. "2000-10-31".
*/
DATE, /**
* The most common ISO Time Format {@code HH:mm:ss.SSSXXX},
* e.g. "01:30:00.000-05:00".
*/
TIME, /**
* The most common ISO DateTime Format {@code yyyy-MM-dd'T'HH:mm:ss.SSSXXX},
* e.g. "2000-10-31T01:30:00.000-05:00".
* <p>This is the default if no annotation value is specified.
*/
DATE_TIME, /**
* Indicates that no ISO-based format pattern should be applied.
*/
NONE
} }
- 其中:
- pattern属性:指定解析/格式化字段数据的模式,如"yyyy-MM-dd HH:mm:ss"。
- 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属性:字符串类型。通过样式指定日期时间的格式。
3.2 数值格式化
- @NumberFormat可对类似数字类型的属性进行标注,它拥有两个互斥的属性:
- style:类型为NumberFormat.Style。用于指定样式类型,包括三种:Style.NUMBER(正常数字类型)、Style.CURRENCY(货币类型)、Style.PERCENT(百分数类型)。
- pattern:类型为String,自定义样式,如pattern="#,###"。
3.3 应用示例
- 示例:
- index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body> <a href="${pageContext.request.contextPath}/test?username=adc&salary=13,500&birthday=2018-09-21">增加数据</a> </body>
</html>
- User.java
package com.sunxiaping.springmvc.domain; import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat; import java.io.Serializable;
import java.util.Date; public class User implements Serializable { private String username; @DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday; @NumberFormat(pattern = "##,###")
private Double salary; public Double getSalary() {
return salary;
} public void setSalary(Double salary) {
this.salary = salary;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
} @Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", birthday=" + birthday +
", salary=" + salary +
'}';
}
}
- UserController.java
package com.sunxiaping.springmvc.controller; import com.sunxiaping.springmvc.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class UserController { @RequestMapping(value = "/test")
public String test(User user){ System.out.println(user); return "success";
} }
- success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
成功啦 <br/> </body>
</html>
- SpringMVC.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd "> <!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.sunxiaping.springmvc"></context:component-scan> <!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean> <mvc:annotation-driven ></mvc:annotation-driven> </beans>
4 数据校验
4.1 概述
- JSR303是java为Bean数据合法性校验提供的标准框架、
- JSR303通过在Bean属性上标注类似于@NotNull、@Max等标准的注解指定校验规则,并通过标准的验证接口对Bean进行校验。
- 常用的注解:
- @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:被标注的元素必须符合指定的正则表达式。
4.2 Hibernate Validator扩展注解
- Hibernate Validator时JSR303的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解:
- @Email:被标注的元素必须是电子邮箱地址。
- @Length:被标注的字符串的大小必须在指定的范围内。
- @NotEmpty:被标准的字符串必须非空。
- @Range:被标准的元素必须在合适的范围内。
4.3 SpringMVC的数据校验
- Spring拥有自己独立的数据校验框架,同时支持JSR303标准的校验框架。
- Spring在进行数据绑定的时候,可以同时调用校验框架完成数据校验工作。在SpringMVC中,可直接通过注解驱动的方式进行数据校验。
- Spring的LocalValidatorFactoryBean既实现了Spring的Validator接口,也实现了JSR303的Validator接口,只要在Spring容器中定义一个LocalValidatorFactoryBean,就可以将其注入到需要数据校验的Bean中。
- Spring本身并没有提供JSR303的实现,所以必须导入JSR303的实现。
- <mvc:annotation-drivern/>会默认装配一个LocalValidatorFactoryBean,通过在处理方法的入参上标注@Valid注解,即可让SpringMVC在完成数据绑定后执行数据校验的工作。
- 在已经标准了JSR303注解的表单对象前标注一个@Valid,SpringMVC框架在将请求参数绑定到该入参对象后,就会调用校验框架根据注解声明的校验规则实施校验。
- SpringMVC是通过对处理方法签名的规则来保存校验结果的:前一个表单对象的校验结果保存到随后的入参中,这个保存校验结果的入参必须是BindingResult或Errors类型,这两个接口都位于org.springframework.validation包中,其中BindingResult继承了Errors接口。
- BindingResult的常用方法:
- 获取所有的FieldError集合:
List<FieldError> getFieldErrors();
- 返回error的错误个数:
int getErrorCount();
- 根据属性名获取FieldError对象:
FieldError getFieldError(String field);
- 根据属性名获取错误信息:
Object getFieldValue(String field);
- 示例:
- 导入hibernate validator坐标:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.2.Final</version>
</dependency>
- index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body> <form action="${pageContext.request.contextPath}/test" method="post">
用户名:<input type="text" name="username"/><br/>
出生日期:<input type="text" name="brithday"/><br/> <input type="submit" value="提交">
</form> </body>
</html>
- User.java
package com.sunxiaping.springmvc.domain; import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import java.io.Serializable;
import java.util.Date; public class User implements Serializable { @NotEmpty(message = "用户名不能为空")
private String username; @DateTimeFormat(pattern = "yyyy-MM-dd")
@NotNull(message = "出生日期不能为空")
@Past(message = "必须比当前日期小")
private Date birthday; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
} }
- UserController.java
package com.sunxiaping.springmvc.controller; import com.sunxiaping.springmvc.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping; import javax.validation.Valid;
import java.util.List; @Controller
public class UserController { @RequestMapping(value = "/test")
public String test(@Valid User user, BindingResult result) { System.out.println(user); int errorCount = result.getErrorCount();
System.out.println("获取错误的个数:" + errorCount); List<FieldError> fieldErrors = result.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
String field = fieldError.getField();
String defaultMessage = fieldError.getDefaultMessage();
System.out.println("属性名:" + field + ",错误消息:" + defaultMessage);
} return "success";
} }
- SpringMVC.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd "> <!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.sunxiaping.springmvc"></context:component-scan> <!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean> <mvc:annotation-driven></mvc:annotation-driven> </beans>
- success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
成功啦 <br/> </body>
</html>
SpringMVC的数据转换&&数据格式化&&数据校验的更多相关文章
- SpringMVC 数据转换 & 数据格式化 & 数据校验
数据绑定流程 1. Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象 ...
- SpringMVC的数据转换,格式化和数据校验
在SpringMVC中,根据请求方法签名不同,将请求消息中的消息以一定的方式转换并绑定到请求方法的参数中,在请求信息到达真正调用处理方法的这一段时间内,SpringMVC还会完成很多其他的 ...
- SpringMVC——数据转换 & 数据格式化 & 数据校验
一.数据绑定流程 1. Spring MVC 主框架将 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框架下数据的增删改查,数据类型转换,数据格式化,数据校验,错误输入的消息回显
在eclipse中javaEE环境下: 这儿并没有连接数据库,而是将数据存放在map集合中: 将各种架包导入lib下... web.xml文件配置为 <?xml version="1. ...
- Spring MVC—数据绑定机制,数据转换,数据格式化配置,数据校验
Spring MVC数据绑定机制 数据转换 Spring MVC处理JSON 数据格式化配置使用 数据校验 数据校验 Spring MVC数据绑定机制 Spring MVC解析JSON格式的数据: 步 ...
随机推荐
- ArcGIS客户端API中加载大量数据的几种解决办法
ArcGIS客户端API中加载大量数据的几种解决办法 2011-03-25 18:17 REST风格的一切事物方兴未艾,ArcGIS Server的客户端API(Javascript/Flex/Sil ...
- C# 虚拟键盘
[DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, uint ...
- RTX系统整合记录
1.切换数据库RTX常见问题解答五. SQL数据库配置 2.同步系统组织机构 部门同步 用户同步https://blog.csdn.net/qq_21703215/article/details/80 ...
- 分布式锁中的基于redis的setnx的原理以及set和setnx的区别是什么
基于Redis实现分布式锁.虽然网上介绍的Redis分布式锁博客比较多,却有着各种各样的问题,本篇博客将详细介绍如何正确地使用setnx实现Redis分布式锁 这里就不介绍错误的示范了 大家直接看正确 ...
- eclipse sts 断点不起作用,把这行 勾上 就行
- 第十周java总结
Java IO 1.file类 file类的构造方法: public Flie(String pathname) -->实例化Flie类的时候,必须设置好路径. 如:Flie f = new F ...
- (5.1.4)引擎管理——SSMS管理使用小技巧
目录 [1]自带报表 [2]对象管理器详细信息 [3]日志 [4]活动监视器 [1]自带报表 无论是数据库.服务器实例.还是代理等等都可以有标准报表 [2]对象管理器详细信息 利用改方式,可以很有效的 ...
- Java第二周总结报告
第二周的学习,开始正式实践进行Java的学习. 本周做了什么? 了解的Java的一些基本知识,如Java变量,数据类型和运算符等.Java变量对不同的数据类型最好采用不同的命名规则,合理的命名有利于提 ...
- 洛谷 P3834 卢卡斯定理 题解
题面 首先你需要知道这条定理: C(n,m)=C(n%p,m%p)*C(n/p,m/p); 这样可以递归实现: 注意坑点:是C(n+m,m),并不是C(n,m); #include <bits/ ...
- Yii中实例化类的四种方式
1.最简单的也是最基本的,大家都会的一种 use yii\caching\FileCache; $cache = new FileCache(); $cache->set("name& ...