1.  数据校验、数据格式化

参考博客 http://www.importnew.com/19477.html

1.1  数据校验

使用 spring 数据校验,先要导入校验器的 jar:

 <!--数据校验-->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.2.Final</version>
</dependency>

此处使用的 hibernate 校验器
JSR 规范:
在实体类的属性上添加注解,可以完成数据校验:
@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(regex=,flag=) 被注释的元素必须符合指定的正则表达式
------------------------------
Hibernate Validator 附加的注解
@NotBlank(message =) 验证字符串非 null,且长度必须大于 0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

如 Employee 实体类中:

 public class  Employee { {
private Integer id;
@NotEmpty( message = " " 用户名不能为空" ")
@Size( min = 3 3, max = 6 6, message = " " 姓名长度应在 {min}- - {max}")
private String name;
@Min( value = 2700, message = " " 工资不能少于 {value}")
@Max( value = 10000, message = " " 工资不能超过 {value}")
private Float salary;

在 springMVC-servlet.xml 中配置校验器:

 <!-- 配置校验器 -->
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- 校验器,使用 hibernate 校验器 -->
<property name="providerClass"
value="org.hibernate.validator.HibernateValidator"/>
</bean>

1.1.1 简单的数据校验

新建 ValidateController

 @Controller
public class ValidateController { {
@RequestMapping( "/val1.html")
public M M odelAndView validate1( @Validated Employee emp, BindingResult result) { {
if ( result. hasErrors()) { { // 如果验证错误
FieldError nameError = result. getFieldError( "name");
FieldError salaryError = result. getFieldError( "salary");
ModelAndView view = new ModelAndView();
view.setViewName( "/validate.jsp"); // 如果 有错就 返回原页面
if ( nameError != null) { {
view.addObject( "nameError", nameError.getDefaultMessage());
} }
if ( salaryError != null) { {
view.addObject( "salaryError", salaryError.getDefaultMessage());
} }
return view;
} }
// 验证成功去首页
return new ModelAndView( "/index.jsp");
} }
} }

@Validated 修饰的参数会被按照规则校验。BindingResult 会存放校验信息。在需要校验的 pojo 前边添加@Validated,在需要校验的 pojo 后边添加 BindingResultbindingResult 接收校验出错信息注意:@Validated 和 BindingResult bindingResult 是配对出现,并且形参顺序是固定的(一前一后)
页面 validate.jsp

 <form action="/val1.html" method="post">
name:<input type="text" name="name"/>${nameError}<br/>
salary:<input type="text" name="salary"/>${salaryError}<br/>
<input type="submit" value="提交"/>
</form>

运行结果:

提交后:

1.1.2  使用@ModelAttribute  和<form:>

spring 有自定义的表单标签,<form:>冒号后面的是生成 html 的标签名,如<form:input>就会生成一个<input>:

 <form:form modelAttribute="empModel" method="post" action="/val2.html">
name:<form:input path="name" /><br/>
<!--输出 name 的校验信息-->
<form:errors path="name"></form:errors><br/>
salary:<form:input path="salary" /><br/>
<form:errors path="salary"></form:errors><br/>
<input type="submit" value="Submit" /><br/>
<!--输出所有错误信息-->
<form:errors path="*"></form:errors>
</form:form>

使用这个标签需要在 jsp 页面中引入头文件:

 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<form:>标签将的 modelAttribute 与 action 对应的方法上@ModelAttribute 修饰的对象对应。要想进入这个页面,首先要经过一个 Controller 的方法,在 Model 中添加对应的属性:

 @RequestMapping( "/goVal2.html")
public String goVal2(Model model) { {
if (! ! model. containsAttribute( "empModel")) { {
l //empModel 与页面中的 <form:form modelAttribute="empModel"> 对应
model. addAttribute( "empModel", new Employee());
} }
return "/validate.jsp";
} }

如果不经过 Controller 或者 Controller 中没有放 empModel 这个属性,那么页面就会报错:

提交表单验证的方法:

 @RequestMapping( "/val2.html")
public String test( @Validated @ModelAttribute( "empModel") Employee emp,
BindingResult result, Model model) { {
// 如果有验证错误 返回到 m form 页面
if ( result. hasErrors()) { {
// 经过 2 goVal2 方法的目的是为了设置 l empModel 属性
// 如果 l empModel 属性没有设置,页面就报错了
return goVal2( model);
} }
return "/index.jsp";
} }

1.1.3 数据校验信息国际化

国际化就是根据浏览器默认语言的不同,显示不同的提示信息:
在 Employee 中,给 id 字段添加验证信息:

 public class  Employee { {
@NotNull( message= "{NotNull.emp.id}")
private Integer

{NotNull.emp.Id}是从 properties 文件中读取属性值
在 resources 目录下创建两个文件,一个用来存放中文提示信息,一个存放英文提示信息:

注意文件的命名,xx.properties 对应的英文配置文件是 xx_en_US.properties
i18n.properties

 NotNull.emp.id=id 不能为空

i18n_en_US.properties

 NotNull.emp.id=userId can not be null

两个文件的 key 是对应的,值是不同的语言
springMVC-servlet.xml 中配置,其中 id=validator 的 bean 前面已经配置过了,这里再添加一个属性即可

 <!-- 配置校验器 -->
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- 校验器,使用 hibernate 校验器 -->
<property name="providerClass"
value="org.hibernate.validator.HibernateValidator"/>
<!--这里添加一个校验信息的数据源-->
<property name="validationMessageSource" ref="messageSource" />
</bean>
<!--自动装配校验器-->
<mvc:annotation-driven validator="validator"/>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<!-- 在 web 环境中一定要定位到 classpath 否则默认到当前 web 应用下找 -->
<value>classpath:i18n</value>
<value>classpath:org/hibernate/validator/ValidationMessages</value>
</list>
</property>
</bean>

使用 1.1.2 节中的测试代码,运行结果:

将浏览器语言切换成英文,刷新页面:

1.2 数据格式化
1.2.1使用注解格式化

springMVC 在映射 Date 类型的属性时会报错:
如果属性是封装在实体类中的,可以使用@DateTimeFormat 注解,如 Employee 中的 hireDate属性。

 @DateTimeFormat( pattern =  "yyyy- - MM- - dd")
private Date hireDate;

12.2.2 initBinder 实现格式化
@DateTimeFormat 是在实体类中格式化日期类型的属性,所有的 Controller 中用到该实
体类都会自动使用注解定义的格式是格式化数据。除此之外,还可以使用@InitBinder 在
Controller 中自定义格式化:

 @Controller
public class DateFormatController { {
// 自定义格式化
@InitBinder
public void initBinder( ServletRequestDataBinder binder) { {
SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy- - MM- - dd");
binder.registerCustomEditor( Date. class,
new CustomDateEditor( dateFormat, true));
} }
@RequestMapping( "/date.html")
public String date( Date date) { {
System. out .println( date);
return "/format.jsp";
} }
} }

@InitBinder 定义的格式化规则对当前 Controller 有效。

1.2.3  自定义格式化

springMVC 有多种方式实现自定义数据格式化,假设现在输入一个电话号码,格式是010-12345678,我们有一个实体类,把区号和电话号码分开:

 public class  PhoneNumModel { {
private String areaCode; // 区号
private String phoneNumber; // 电话号码
//getter/setter 方法略
} }

当请求中传入一个 String 类型的参数“010-12345678”,通过 springMVC 的数据格式化,可以把 String 转换成实体类 PhoneNumModel
第一种方式:定义一个转换工具类,继承 PropertyEditorSupport

 public class  PhoneNumConverter  implements Converter< < String,  PhoneNumModel > {
// 正则表达式,定义数据规则
Pattern pattern = = Pattern.compile( "^(\\ d{3,4})- -( (\\ d{7,8})$");
@Override
public PhoneNumModel convert( String s s) { {
if ( s == null || !StringUtils.hasLength(s s)) { {
return null; // 如果没值,设值为 null
} }
Matcher matcher = pattern.matcher(s s);
if ( matcher.matches()) { {
PhoneNumModel phoneNumber = new PhoneNumModel();
phoneNumber.setAreaCode( matcher.group(1 1));
phoneNumber.setPhoneNumber( matcher.group(2 2));
return phoneNumber;
} else { {
throw new IllegalArgumentException( String.format(" " 类型转换失败,需要格
式 [010- - 12345678] ,但格式是 [%s]", s s));
} }
} }
} }

Controller 中使用@InitBinder 注册自定义转换器:

 @Controller
public class MyBinderController { {
// 自定义格式化
@InitBinder
public void initBinder( WebDataBinder binder) { {
binder.registerCustomEditor( PhoneNumModel. class, new PhoneNumEditor());
} }
@RequestMapping( "/phone.html") // 注意一定要写 @RequestParam
public ModelAndView phone( @RequestParam( "phone") PhoneNumModel phone) { {
// 绑定成功时可以看到输出
System. out .println( phone.getAreaCode());
System. out .println( phone.getPhoneNumber());
return new ModelAndView( "/format.jsp", "phone", phone);
} }
} }

测试分 url:
http://localhost:8080/phone.html?phone=010-1234567
通过@InitBinder 的方式,数据绑定规则只对当前 Controller 有效
在 Spring4.2 之后提出了一种新的转换方式,工具类实现 Converter 接口:

 public class  PhoneNumConverter  implements Converter< < String,  PhoneNumModel > {
// 正则表达式,定义数据规则
Pattern pattern = Pattern.compile( "^(\\ d{3,4})- -( (\\ d{7,8})$");
@Override
public PhoneNumModel convert( String s s) { {
if ( s == null || !StringUtils.hasLength(s s)) { {
return null; // 如果没值,设值为 null
} }
Matcher matcher = pattern.matcher(s s);
if ( matcher.matches()) { {
PhoneNumModel phoneNumber = new PhoneNumModel();
phoneNumber.setAreaCode( matcher.group(1 1));
phoneNumber.setPhoneNumber( matcher.group(2 2));
return phoneNumber;
} else { {
throw new IllegalArgumentException( String.format(" " 类型转换失败,需要格
式 [010- - 12345678] ,但格式是 [%s]", s s));
} }
} }
} }

在 springMVC 配置文件中注册自定义转换器:

 <!-- 需要将转换器设置给注解驱动 -->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>
<bean id="conversionServiceFactoryBean"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="util.PhoneNumConverter"></bean>
</set>
</property>
</bean>

Controller 中不需要写@InitBinder 了。这个配置对所有 Controller 都生效。

2.  其它注解

2.1 @CookieValue

 @RequestMapping( "cookie.html")
public String cookie( @CookieValue( value = "JSESSIONID", defaultValue = "mysession")
String jsessionId) { {
System. out .println( jsessionId);
return "/index.jsp";
} }

@CookieValue 用于获取 cookie 信息。value 用于指定 cookie 的名字,defaultValue 是当对应的 cookie 为空时系统设置的默认值。required 设置为 true 表示必须。
上面的代码如果浏览器中没有 cookie,会输出 mysession。再次刷新页面,就会打印出当前的 jsesessionid,如:

2.2 @Value

@Value 可以实现从配置文件中读取数据并注册给 Controller 在 springMVC 配置文件种加载 properties 文件:

 <context:property-placeholder location="classpath:*.properties"/>

测试代码,这里读取的是 12.1.3 中配置文件中的 key

 // 从配置文件中读取属性
@Value( "${NotNull.emp.id}")
private String NOT_NULL_ID;
@RequestMapping( "value.html")
public String value() { {
System. out .println( NOT_NULL_ID);
return "/index.jsp";
} }

3. 数据绑定流程

  1. ApplicationContext 初始化时建立所有 url 和 controller 类的对应关系(用 Map 保存);
  2. 根据请求url找到对应的controller,并从controller中找到处理请求的方法
  3. Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象
  4. DataBinder 是数据绑定的核心部件,调用装配在 Spring MVC 上下文中的 ConversionService 组件进行数据类型转换、数据格式化工作。将 Servlet中的请求信息填充到入参对象中
  5. 调用 Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象
  6. Spring MVC 抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的响应入参。

springMVC整理05--数据校验、格式化 & 其他注解 & 数据绑定流程的更多相关文章

  1. SpringMvc中的数据校验

    SpringMvc中的数据校验 Hibernate校验框架中提供了很多注解的校验,如下: 注解 运行时检查 @AssertFalse 被注解的元素必须为false @AssertTrue 被注解的元素 ...

  2. 【SpringMVC学习06】SpringMVC中的数据校验

    这一篇博文主要总结一下springmvc中对数据的校验.在实际中,通常使用较多是前端的校验,比如页面中js校验,对于安全要求较高的建议在服务端也要进行校验.服务端校验可以是在控制层conroller, ...

  3. springMVC使用JSR303数据校验

    JSR303注解 hibernate validate是jsr 303的一个参考实现,除支持所有的标准校验注解外,他还支持扩展注解 spring4.0拥有自己独立的数据校验框架,同时支持jsr 303 ...

  4. SpringMvc数据校验@Valid等注解的使用与工具类抽取

    最近在重构老项目的代码,发现校验入参占用了很多代码,之前我对这一块的认识局限于使用StringUtils等工具来多个if块进行判断,代码是没什么问题,但是总写这些令人生烦,毕竟写代码也要讲究优雅的嘛, ...

  5. Spring MVC—数据绑定机制,数据转换,数据格式化配置,数据校验

    Spring MVC数据绑定机制 数据转换 Spring MVC处理JSON 数据格式化配置使用 数据校验 数据校验 Spring MVC数据绑定机制 Spring MVC解析JSON格式的数据: 步 ...

  6. 用spring的@Validated注解和org.hibernate.validator.constraints.*的一些注解在后台完成数据校验

    这个demo主要是让spring的@Validated注解和hibernate支持JSR数据校验的一些注解结合起来,完成数据校验.这个demo用的是springboot. 首先domain对象Foo的 ...

  7. SpringBoot入门 (十一) 数据校验

    本文记录学习在SpringBoot中做数据校验. 一 什么是数据校验 数据校验就是在应用程序中,对输入进来得数据做语义分析判断,阻挡不符合规则得数据,放行符合规则得数据,以确保被保存得数据符合我们得数 ...

  8. SpringMVC框架下数据的增删改查,数据类型转换,数据格式化,数据校验,错误输入的消息回显

    在eclipse中javaEE环境下: 这儿并没有连接数据库,而是将数据存放在map集合中: 将各种架包导入lib下... web.xml文件配置为 <?xml version="1. ...

  9. SpringMVC 数据转换 & 数据格式化 & 数据校验

    数据绑定流程 1. Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象 ...

随机推荐

  1. MemSQL与MySQL不兼容问题总结

    1.数据行Update更新数据行时,如果数据行没有变化,MySQL返回受影响的数据行数为1,但MemSQL返回的数据行数为0. 2.MemSQL不支持唯一约束 3.MemSQL不支持外键约束

  2. 剑指offer--2.替换空格

    题目: 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 思路:可以使用replace或者 ...

  3. rest-framework的权限组件

    权限组件 写在开头: 首先要在models表中添加一个用户类型的字段: class User(models.Model): name=models.CharField(max_length=32) p ...

  4. 【转】linux下查看磁盘分区的文件系统格式

    https://www.cnblogs.com/youbiyoufang/p/7607174.html

  5. Migrate MySQL database using dump and restore

    kaorimatz/mysqldump-loader: Load a MySQL dump file using LOAD DATA INFILEhttps://github.com/kaorimat ...

  6. PHP导出CSV文件出现乱码的解决方法

    在做项目时碰到使用外语的情况下,我们就会使用UTF-8编码.但是,在用PHP导出CSV文件时,如果写入的数据是使用UTF-8编码的日语.韩语之类的外文,就会出现乱码. 要解决PHP生成CSV文件的乱码 ...

  7. Python PEP8 编码规范中文版

    原文链接:https://legacy.python.org/dev/peps/pep-0008/ 参考:https://blog.csdn.net/ratsniper/article/details ...

  8. react初入门

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. php 对象赋值后改变成员变量影响赋值对象

    话不多说看代码 打印结果 对obj1的操作 直接影响了obj2 , 对obj2的操作 直接影响了obj1

  10. laravel创建项目

    composer create-project --prefer-dist laravel/laravel=5.5.* blog