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. Vue(二)基础

    01-vue的起步 1.引包 a) 直接下载,并用<script>标签引入 b) CDN方式引入: <script src="https://cdn.bootcss.com ...

  2. SDN 实验室学生们

    SDN实验室系列:https://edu.cnblogs.com/campus/fzu/SdnLab --研究生及本科生们的博客及GitHub链接.欢迎各位大佬招募. 研究生 2018级 姓名 博客地 ...

  3. 牛客练习赛B题 筱玛的排列(找递推规律)

    链接:https://ac.nowcoder.com/acm/contest/342/B来源:牛客网 筱玛的排列 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语 ...

  4. 《梦断代码》Scott Rosenberg著(二)

    书中有一段说的是一个闪烁缺陷——在改变某软件中某个窗体的尺寸时,屏幕会闪烁一秒钟左右.虽然该缺陷不会影响程序运行,但它不符合作者的审美观,历时六个多月仍然没能修正.其实在日常的编程中也有许多小bug的 ...

  5. 后台管理系统之邮件开发(Java实现)

    一,功能点 后台管理系统,添加用户时.对注册的新用户邮箱发送初始密码. 二,代码实现 1.Mail实体类 public class Mail { private Set<String> r ...

  6. Java Core - 序列化和反序列化

    把对象转换为字节序列的过程称为对象的序列化 把字节序列恢复成对象的过程称为对象的反序列化 一.对象的序列化的应用: 1.把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中. 2.在网络上传送对象 ...

  7. Docker常规防止容器自动退出

    [root@server-crm /]# docker attach songheng [root@fc0a891e1861 /]# cat /bin/auto_service.sh #!/bin/s ...

  8. Oracle RMAN备份与还原

    RMAN在数据库服务器的帮助下实现数据库文件.控制文件.数据库文件与控制文件的映像副本.归档日志文件.数据库服务器参数文件的备份. RMAN的特点: (1) 支持增量备份:传统的exp与expdp备份 ...

  9. Html5使用canvas作图

    以下例子是项目中实际用到的.不足之处请大家指正,设计到画线,写文字,填充,文字旋转. <!DOCTYPE html> <html> <head lang="en ...

  10. [FreeBuff]Trojan.Miner.gbq挖矿病毒分析报告

    Trojan.Miner.gbq挖矿病毒分析报告 https://www.freebuf.com/articles/network/196594.html 竟然还有端口转发... 这哥们.. 江民安全 ...