数据校验是 Web 应用为了安全必须处理的步骤,Spring MVC 提供了两种方法来对用户的输入数据进行校验,一种是 Spring 自带的 Validation 校验框架,另一种是利用 JRS-303 验证框架进行验证。

在实际开发中我们不是使用 Spring 自带的框架,而是使用 JRS 相关验证框架(Hibernate validator)完成开发。 Hibernate-validator 是根据 Bean Validation 的参考实现,遵循 Bean Validation 2.0 规范,基于 JSR 380 实现。

1 Bean Validation website

Bean Validation 中内置的 constraint 如下:

注解 作用
@Valid 被注释的元素是一个对象,需要检查此对象的所有字段值
@Null 被注释的元素必须为 null
@NotNull 被注释的任何元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Negative 被注释的元素必须是一个负数
@NegativeOrZero 被注释的元素必须是负数或 0
@Positive 被注释的元素必须是一个正数
@PositiveOrZero 被注释的元素必须是一个正数或 0
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@PastOrPresent 被注释的元素必须是一个过去或当前的日期
@Future 被注释的元素必须是一个将来的日期
@FutureOrPresent 被注释的元素必须是一个将来或当前的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
@NotEmpty 集合对象的元素不为0,即集合不为空,也可以用于字符串不为 null
@NotBlank 只能用于字符串不为null,并且字符串trim()以后length要大于0
@Email 被注释的元素必须是一个有效的邮箱地址

2 Hibernate Validator

Hibernate Validator 完全遵循了 Bean Validation 的规范,并在其基础上有附加的扩展。

注解 作用
@CreditCardNumber(ignoreNonDigitCharacters=) 被注释的字符串必须通过 Luhn 校验算法,银行卡,信用卡等号码一般都用 Luhn 计算合法性
@Currency(value=) 被注释的 javax.money.MonetaryAmount 货币元素是否合规
@DurationMax(days=, hours=, minutes=, seconds=, millis=, nanos=, inclusive=) 被注释的元素不能大于指定日期
@DurationMin(days=, hours=, minutes=, seconds=, millis=, nanos=, inclusive=) 被注释的元素不能低于指定日期
@EAN 被注释的元素是否是一个有效的 EAN 条形码
@Length(min=, max=) 被注释的字符串的大小必须在指定的范围内
@LuhnCheck(startIndex= , endIndex=, checkDigitIndex=, ignoreNonDigitCharacters=) Luhn 算法校验字符串中指定的部分
@Mod10Check(multiplier=, weight=, startIndex=, endIndex=, checkDigitIndex=, ignoreNonDigitCharacters=) Mod10 算法校验
@Mod11Check(threshold=, startIndex=, endIndex=, checkDigitIndex=, ignoreNonDigitCharacters=, treatCheck10As=, treatCheck11As=) Mod11 算法校验
@Range(min=, max=) 被注释的元素必须在合适的范围内
@SafeHtml(whitelistType= , additionalTags=, additionalTagsWithAttributes=, baseURI=) classpath中要有jsoup包
@ScriptAssert(lang=, script=, alias=, reportOn=) 检查脚本是否可运行
@URL(protocol=, host=, port=, regexp=, flags=) 被注释的字符串必须是一个有效的url

3 Test

3.1 Manev 导包

使用 manev 导入相关包。 这里只展示 spring-mvc 和 hibernate-validator 包。

<dependencies><!-- spring-mvc--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.0.0.RELEASE</version></dependency><!-- hibernate-validator --><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.0.2.Final</version></dependency>
</dependencies>

3.2 国际化配置

Hibernate Validator 默认国际化文件是 ValidationMessages.properties,存放的位置在 org.hibernate.validator,我们可以在项目根目录增加此默认文件自动替换达 Hibernate 的资源文件达到国际化的目的。多数情况项目是插件开发,各大业务线是自定义国际化文件的。这里我们添加一个文件 ValidationMessages_zh_CN.properties。

username.NotEmpty = 用户名不能为空
password.NotEmpty = 密码不能为空
password.Size = 密码长度应在{min}-{max}个字符

3.3 Xml 配置

3.3.1 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://xmlns.jcp.org/xml/ns/javaee"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"id="yjcocoa"version="3.1"><!-- 配置spring mvc 前端核心控制器--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-config.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 系统默认页面--><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list></web-app>

3.3.2 springmvc-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 配置视图解释器ViewResolver --><bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/></bean><!-- 配置扫描器 --><context:component-scan base-package="com.springmvc"/><!--配置注解驱动  --><mvc:annotation-driven/><!--配置静态资源的访问映射,此配置中的文件,将不被前端控制器拦截 --><mvc:resources location="/js/" mapping="/js/**"/><!-- 配置校验器 --><!--国际化校验资源--><bean id="hibernateValidationMessages" class="org.springframework.context.support.ResourceBundleMessageSource"><property name="defaultEncoding" value="UTF-8"/><property name="basenames"><list><!--多模块自定义校验文档--><value>ValidationMessages</value></list></property></bean><!--属性校验--><bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"><!-- 校验器,使用hibernate校验器 --><property name="providerClass" value="org.hibernate.validator.HibernateValidator"/><property name="validationMessageSource" ref="hibernateValidationMessages"/></bean><!--方法校验--><bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"><property name="validator" ref="validator"/></bean></beans>

除了对实例类的属性校验,我们还可以通过 MethodValidationPostProcess 对方法参数进行校验。这样我们就不需要分组校验,只需要自定义方法即可达到分组校验的效果,进一步精简了代码。Spring 衔接 Hibernate Validator 只需配置一个 validator Bean 元素即可,并制定 bean 名称 validator,spring mvc 会默认加载 validator 校验器。国际化主要通过 ResourceBundleMessageSource 加载资源文件并注入 LocalValidatorFactoryBean 中。

3.4 JSP 页面

页面主要是index.jsp,其中 success.jsp就不再展示。

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8" %>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>登录</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/validator/login"method="post">用户名:<input type="text" name="username" value=${user.username}> <span>${usernameValid}</span><br/>密&nbsp;&nbsp;&nbsp;码:<input type="text" name="password" value=${user.password}><span>${passwordValid}</span><br/><input type="submit" value="登录"/>
</form>
</body>
</html>

页面使用 from 提交。并使用 ${} 获取数据。

3.5 Java 类

3.5.1 PO类

package com.springmvc.po;import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;public class User {@NotEmpty(message = "{username.NotEmpty}")private String username;@NotEmpty(message = "{password.NotEmpty}")@Size(min = 6, max = 9, message = "{password.Size}")private String password;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;}}

这里可直接看到注解校验的好处,开发简单,可维护性很高。国际化资源文件的写法使用了 {key} 的方式。

3.5.2 控制器

package com.springmvc.controller;import com.springmvc.po.User;
import com.springmvc.service.ValidatorService;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Valid;/*** ValidatorController.java* <p>* Created by 阳君 on 2017/10/16.* Copyright © 2017年 springmvc. All rights reserved.*/
@Controller
@RequestMapping("/validator")
public class ValidatorController {@Autowiredprivate ValidatorService validatorService;@RequestMapping("")public String index() {return "validator/index";}@RequestMapping("/login")public String login(Model model, @Valid User user, BindingResult bindingResult) {if (bindingResult.hasErrors()) {for (ObjectError objectError : bindingResult.getAllErrors()) {FieldError fieldError = (FieldError) objectError;model.addAttribute(fieldError.getField() + "Valid", objectError.getDefaultMessage());}return "validator/index";}model.addAttribute("msg", user.toString());return "validator/success";}@RequestMapping("/login2")public String login2(Model model, User user) {try {model.addAttribute("msg", this.validatorService.checkUser(user.getUsername(), user.getPassword()));} catch (ConstraintViolationException e) {for (ConstraintViolation constraintViolation : e.getConstraintViolations()) {String key = ((PathImpl) constraintViolation.getPropertyPath()).getLeafNode().getName() + "Valid";model.addAttribute(key, constraintViolation.getMessage());}return "validator/index";}return "validator/success";}}

这里使用 fieldError.getField() + "Valid" 组成统一格式的校验反馈。login 实现了实例化的属性校验,login2 通过 validatorService 完成了方法的校验。

3.5.3 业务层

package com.springmvc.service;import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;import javax.validation.ConstraintViolationException;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;/*** ValidatorService.java* <p>* Created by 阳君 on 2017/10/16.* Copyright © 2017年 springmvc. All rights reserved.*/
@Validated
@Service
public class ValidatorService {public String checkUser(@NotEmpty(message = "{username.NotEmpty}")String username,@NotEmpty(message = "{password.NotEmpty}")@Size(min = 6, max = 9, message = "{password.Size}")String password) throws ConstraintViolationException {return "User [username=" + username + ", password=" + password + "]";}}

业务层的 checkUser 方法实现了方法校验,当校验不通过时会报 ConstraintViolationException 错误。

3.5 效果图

运行项目,点登录,即可看见如下效果。


Appendix

Sample Code

Java

Related Documentation

spring-framework-reference

Bean Validation 2.0

Validator 6.0.2.Final

Revision History

时间 描述
2017-10-17 博文完成

Copyright

CSDN:http://blog.csdn.net/y550918116j

GitHub:https://github.com/937447974

Spring Hibernate Validation相关推荐

  1. Spring Boot 后台验证 Hibernate Validation

    后台验证详解 开发项目过程中,后台在很多地方需要进行校验操作,比如:前台表单提交,调用系统接口,数据传输等.而现在多数项目都采用MVC分层式设计,每层都需要进行相应地校验. 针对这个问题, JCP 出 ...

  2. Hibernate Validation校验注解详解

    在前后端传递数据的时候,往往后端需要校验传递数据的格式,比如用户名的格式,密码是否为空.我们可以在service层编写代码判断,但是当我们在多处需要校验传递来的数据的时候,就会出现大量重复的代码,一旦 ...

  3. Spring Boot Validation

    Spring Boot Validation是Spring Boot整合了Hibernate Validation的一个框架,其核心是Hibernate Validation,此框架的作用是检验客户端 ...

  4. Spring Boot Validation提示信息国际化配置

    引言 之前介绍过Spring Boot Validation的使用及扩展,可参见:<SpringBoot Validation> 本文在此基础上重点讲解下Spring Boot Valid ...

  5. ssh(Struts+spring+Hibernate)三大框架整合-简述

    ssh(Struts+spring+Hibernate)三大框架配合使用来开发项目,是目前javaee最流行的开发方式,必须掌握: 注意: 为了稳健起见,每加入一个框架,我们就需要测试一下,必须通过才 ...

  6. struts+spring+hibernate总结

    简单的说: struts 控制用的 hibernate 操作数据库的 spring 用解耦的 详细的说: struts 在 ssh 框架中起控制的作用 , 其核心是 Controller, 即 Act ...

  7. 【SSH进阶之路】Struts + Spring + Hibernate 进阶开端(一)

    Long Long ago.就听说过SSH.起初还以为是一个东东,详细内容更是不详,总认为高端大气上档次,经过学习之后才发现,不不过高大上,更是低调奢华有内涵,经过一段时间的研究和学习SSH框架的基本 ...

  8. java ssh框架 struts spring hibernate 简介

    目录 什么是SSH框架 浅谈Struts 什么是Struts Struts的核心构成 为什么使用Struts 浅谈Hibernate 什么是Hibernate Hibernate的核心构成 浅谈Spr ...

  9. pytorch1.0.1_将Spring 3.x和Hibernate 3.x升级到Spring Platform 1.0.1(Spring + hibernate 4.x)

    pytorch1.0.1 最近,我自愿将我们的最新项目升级到最新版本的Spring Platform. Spring Platform为您提供的是整个Spring框架库集中的依赖项和插件管理. 由于我 ...

  10. SSH之IDEA2017整合Struts2+Spring+Hibernate

    摘要 IDEA无疑是Java编程的利器,在下面我们将介绍如何使用IDEA来整合SSH(Struts2 + Spring + Hibernate):介绍將分为三个部分来讲,分别是新建工程,Spring引 ...

最新文章

  1. php面向对象程序设计,PHP面向对象程序设计类的定义与用法简单示例
  2. zend framework1.11使用原生代码获取结果
  3. Arthas 征文活动火热进行中,cherry 键盘等你来拿!(内附第三期中奖名单)
  4. 线程的控制(创建、等待、终止)、分离线程
  5. 流浪的python博客园_python学习心得第一章
  6. yii2 mysql查询_Yii2 数据库查询汇总
  7. 事物注解方式: @Transactional
  8. 字符串匹配(一)—— KMP / MP
  9. 你知道,什么时候用Vue计算属性吗?
  10. C#-求int数组中连续偶数列的个数
  11. 6.UNIX 环境高级编程--系统数据文件和信息
  12. pytorch中torch.max和F.softmax函数的维度解释
  13. UWB与蓝牙AOA定位技术简要对比
  14. 范浩强树的学习历程,同时附加一个例题HDU4585shaolin
  15. 如何在eclipse中新建java web项目,并且生成的是WebRoot目录而不是WebContent
  16. 如何提取html 信息,从html中提取信息?
  17. 【第一组】第七次冲刺例会纪要
  18. 如何查看同一服务器上挂有多少个网站
  19. sqlserver无法连接的localhost解决方案
  20. 事务的4个特性——ACID(原子性、一致性、隔离性和持久性)、更新丢失问题...

热门文章

  1. Guideline 2.3.3 -- We noticed that your screenshots do not sufficiently reflect your app in use
  2. 211逆袭浙大-计算机及相关衍生专业保研之路纪实(深度长文,收藏了)
  3. 信息孤岛的形成与治理
  4. win10自带sftp服务器_win10开启sftp服务器
  5. 如迷的解谜者——Alan Turing
  6. E - Antinomy与红玉海
  7. ae合成设置快捷键_AE超实用快捷键你了解多少?
  8. React Native 填坑记录01
  9. python psutil 汇总 tcy
  10. 人工智能 2 级就来越塔来杀我,论文已被NeurIPS收录!