springMVC中两种validation的简单使用

2023-10-27


本文转自:http://elf8848.iteye.com/blog/1299587


Spring 基于注释的校验机制:


1)支持JSR303 Bean Validation定义的校验规范。


2) 支持Spring框架定义的Validator接口定义的校验。

表单:user.jsp

注册用户包含三项信息: 用户名,密码,邮箱。

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>User Register Page</title>
<style type="text/css">
.error{
color: red;
}
</style>
</head>

<body>
<%--
这里指定页面绑定的对象 modelAttribute. 之前很困惑,
为什么<form>上最重要的 <form action="someAction.do">属性没了呢? 
后来发现,其实在controller中的方法以及指定了地址到method的对应关系,
<form>里的action属性就可以退休了。
--%>
<sf:form method="post" modelAttribute="user">
<p>用户注册页面:</p>
<table width="60%" align="center">
<colgroup>
<col width="10%" align="right" />
<col />
</colgroup>
<tr>
<th>用户名:</th>
<td>
<sf:input path="userName" />
<small>length of userName is not more than 20.</small><br />
<%-- 显示关于userName属性相关的错误信息。 --%>
<sf:errors path="userName" cssClass="error"/>
</td>
</tr>
<tr>
<th>密码:</th>
<td>
<sf:password path="password" />
<small>length of password is not less than 6.</small><br />
<sf:errors path="password" cssClass="error" />
</td>
</tr>
<tr>
<th>邮箱:</th>
<td>
<sf:input path="email"/>
<small>format should confirm to general standard.</small><br />
<sf:errors path="email" cssClass="error" />
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="注册" />
</td>
</tr>
</table>
</sf:form>
</body>
</html>


与上述form中对应的user对象如下:

public class User {
private String userName;

private String password;

private String email;

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 String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}

public String toString(){
StringBuilder sb = new StringBuilder();

sb.append(getClass()).append("[")
.append("userName=").append(userName).append(", ")
.append("password=").append(password).append(", ")
.append("email=").append(email).append("]");

return sb.toString();
}

}


在这里不讨论前端JS的校验,只说明SpringMVC中的后台校验机制。


校验方式一: JSR303 Bean Validation

Spring3.1后增加的了对JSR303 Bean Validation规范的支持,不仅可以对Spring的 MVC进行校验,而且也可以对Hibernate的存储对象(POJO)进行校验,是一个通用的校验框架。

环境准备:

A) 导入Hibernate-Validator  
要使用JSR303 校验框架, 需要加入框架的具体实现Hibernate-Validator, 在
http://mvnrepository.com/上下载最新的Hibernate-Validator , 

当前版本为5.2.4 Final版。
在/WEB-INF/lib中导入 hibernate-validator-5.2.4.Final.jar, hibernate-validator-annotation-processor-5.2.4.Final.jar, 

导入它的lib/required目录下内容slf4j-api-1.7.2.jar, validation-api-1.1.0.Final.jar;

B) 配置Spring对JSR 303 的支持。 
在你的springMVC的配置文件中增加如下配置:配置对JSR303的支持,包括自动查找Hibernate-Validator的实现等工作。

<mvc:annotation-driven />


校验属性的Constraints的设定


该步骤就是对校验对象的属性使用JSR303原生的注解Constraints对需要校验的属性进行约束限定。

在JSR303中已经定义的Constraint如下:

空检查

@Null       验证对象是否为null

@NotNull     验证对象是否不为null, 无法查检长度为0的字符串

@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.

@NotEmpty 检查约束元素是否为NULL或者是EMPTY.

 

Booelan检查

@AssertTrue     验证 Boolean 对象是否为 true  

@AssertFalse    验证 Boolean 对象是否为 false  

 

长度检查

@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  

@Length(min=, max=) 验证字符串的长度是否在给定的范围之内,包含两端

 

日期检查

@Past        验证 Date 和 Calendar 对象是否在当前时间之前  

@Future     验证 Date 和 Calendar 对象是否在当前时间之后  

@Pattern    验证 String 对象是否符合正则表达式的规则

 

数值检查:建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null

@Min            验证 Number 和 String 对象是否大等于指定的值  

@Max            验证 Number 和 String 对象是否小等于指定的值  

@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度

@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度

@Digits     验证 Number 和 String 的构成是否合法  

@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。

 

@Range(min=, max=) Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.

@Range(min=10000,max=50000,message="range.bean.wage")
private BigDecimal wage;

@Valid递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)

@CreditCardNumber信用卡验证

@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。

@ScriptAssert(lang= ,script=, alias=)

@URL(protocol=,host=, port=,regexp=, flags=)


通过上述Constraint约束后的User对象如下:

package org.study.domain;


import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;


import org.study.validation.annotation.NotEmpty;


public class User {

@Size (min=3, max=20, message="用户名长度只能在3-20之间")
private String userName;

@Size (min=6, max=20, message="密码长度只能在6-20之间")
private String password;

@Pattern (regexp="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}", message="邮件格式错误")
private String email;

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 String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}

public String toString(){
StringBuilder sb = new StringBuilder();

sb.append(getClass()).append("[")
.append("userName=").append(userName).append(", ")
.append("password=").append(password).append(", ")
.append("email=").append(email).append("]");

return sb.toString();
}

}


Validate的触发
在需要校验的对象前加 @Valid 注解 (该注解位于javax.validation包中)来触发校验。示例如下:

/**
* 处理提交的用户注册信息。
* @param model
* @return
*/
@RequestMapping (method = RequestMethod.POST)
public String doRegister(@Valid User user, BindingResult result){
if(logger.isDebugEnabled()){
logger.debug("process url[/user], method[post] in "+getClass());
}
//校验没有通过
if(result.hasErrors()){
return "user";
}
if(user != null){
userService.saveUser(user);
}

return "user";
}


这样就可以完成针对输入数据User对象的校验了, 校验结果任然保存在BindingResult对象中。


校验方式二: Spring Validator 

Validator接口的实现:


Spring框架的Validator接口定义:

package org.springframework.validation;

public interface Validator {

boolean supports(Class<?> clazz);

void validate(Object target, Errors errors);
}


要使用它进行校验必须实现该接口。实现Validator接口的代码如下:

package org.study.validation.validator;


import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import org.study.domain.User;


public class UserValidator implements Validator {


@Override
public boolean supports(Class<?> clazz) {
return clazz.equals(User.class);
}


@Override
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmpty(errors, "userName", "user.userName.required", "用户名不能为空");
ValidationUtils.rejectIfEmpty(errors, "password", "user.password.required", "密码不能为空");
ValidationUtils.rejectIfEmpty(errors, "email", "user.email.required", "邮箱不能为空");
User user = (User)target;
int length = user.getUserName().length();
if(length>20){
errors.rejectValue("userName", "user.userName.too_long", "用户名不能超过{20}个字符");
}
length = user.getPassword().length();
if(length <6){
errors.rejectValue("password", "user.password.too_short", "密码太短,不能少于{6}个字符");
}else if(length>20){
errors.rejectValue("password", "user.password.too_long", "密码太长,不能长于{20}个字符");
}
int index = user.getEmail().indexOf("@");
if(index == -1){
errors.rejectValue("email", "user.email.invalid_email", "邮箱格式错误");
}
}

}


设置Validator,并触发校验


在我们的Controller中需要使用父类已有的方法来为DataBinder对象指定Validator,  protected initBinder(WebDataBinder binder); 代码如下:

@InitBinder
protected void initBinder(WebDataBinder binder){
binder.setValidator(new UserValidator());
}

为binder对象指定好Validator校验对象后,下面一步的就是在需要校验的时候触发validate方法,该触发步骤是通过 @Validated 注解(该注解是Spring框架定义的)实现的。

/**
* 处理提交的用户注册信息。
* @param model
* @return
*/
@RequestMapping (method = RequestMethod.POST)
public String doRegister(@Validated User user, BindingResult result){
if(logger.isDebugEnabled()){
logger.debug("process url[/user], method[post] in "+getClass());
}
//校验没有通过
if(result.hasErrors()){
return "user";
}

if(user != null){
userService.saveUser(user);
}

return "user";
}


至此,从页面提交的User对象可以通过我们实现的UserValidator类来校验了,校验的结果信息存入BindingResult result对象中。在前台页面可以使用spring-form的标签<sf:errors path="*" />来显示。




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springMVC中两种validation的简单使用 的相关文章

随机推荐

  • TCP报文段首部格式介绍

    1 TCP报文段首部格式tu 2 头部各个字段介绍 1 源端口和目的端口 源端口和目的端口字段各占 2 字节 端口是运输层与应用层的服务接口 运输层的复用和分用功能都要通过端口才能实现 2 序号字段 序号字段占 4 字节 要明确的是 TCP
  • WebService报错javax.xml.ws.soap.SOAPFaultException: javax.xml.ws.WebFault.messageName()

    原文地址 http blog csdn net woshixuye article details 14312579 一 发现问题 JAX WS规范是一组XML web services的JAVA API JAXWS RI是其的一个包 用j
  • 面试-大数据-场景题-sql

    1 求5min内浏览次数达到100的用户 LAG和LEAD函数 转载自 有如下场景 某公司网站每日访问量达到10亿级别的访问量 每次访问记录一条数据 数据包含如下字段 用户ID 访问时间 毫秒级 访问页面 要求使用hive求出所有在5分钟内
  • 卷积神经网络的三个特性

    转载 elecfans com emb fpga 20171116580425 2 html 局部感知 形象地说 就是模仿你的眼睛 想想看 你在看东西的时候 目光是聚焦在一个相对很小的局部的吧 严格一些说 普通的多层感知器中 隐层节点会全连
  • 关于C#模拟LED

    如下图 不管是用什么控件 或者是richTextBox 或者是TextBox 等等 我想应该都可以做得出下面这种效果来 但是 本人研究了快半个月了 可以说也没有找到什么很好的头绪 所以 干脆就粘贴在我的博客中了 希望看到的朋友给我个意见或者
  • c语言在输入字符串时输入空格的方式

    1 最容易的 将一个字符串分为一个一个字符输入 char s 100 int i 0 while scanf c s i s i n i s i 0 遇到换行停止输入 并且将换行替换为 0 printf s n s 但是如果在这段程序前还有
  • 每日一题:最大和上升子序列

    最大和上升子序列 题目 Daimayuan Online Judge 动态规划 和最长上升子序列类似 状态划分 以第i个数结尾的上升子序列的倒数第二个数可能是第一个数 第二个数 第i 1个数 从第一个数开始枚举 以它为结尾 首先f i a
  • bboss 流批一体化框架 与 数据采集 ETL

    数据采集 ETL 与 流批一体化框架 特性 高效 稳定 快速 安全 bboss 是一个基于开源协议 Apache License 发布的开源项目 主要由以下三部分构成 Elasticsearch Highlevel Java Restcli
  • feign调用使用Apache Http遇到问题汇总

    feign调用使用Apache Http目前已知会造成三个问题 1 RequestMapping必须显式指定调用方式 method RequestMethod POST 否则默认会使用get请求 这会造成之前一些没有显式指定调用方式的方法报
  • linux下quartus出现ModelSim executable not found和Unable to checkout a license. Make sure...... 错误

    一定要把Tools gt Options gt EDA Tool Options设置到bin下YOUR PATH altera 13 1 modelsim ase bin 注意是modelsim ase不是modelsim ae 而且有bi
  • C++内存分析工具

    C 内存分析工具 背景 内存泄漏在c 中是一个常见的问题 有一个好用的内存分析工具就是很有必要的 下面来介绍两个简单好用的内存分析工具 Valgrind和Sanitizer Valgrind valgrind是一种非侵入式的内存检测工具 在
  • TTS

    FastSpeech 基于 Transformer 的前馈网络 用于并行生成 TTS 梅尔谱图 FastSpeech 模型与自回归 Transformer TTS 相比 梅尔谱图生成速度加快了 270 倍 端到端语音合成速度加快了 38 倍
  • 【电商专享】聚划算活动海量商品一键报名,省时省力!

    电商专享 聚划算活动海量商品一键秒参与 省时省力 本机器人支持自动登录淘宝账号 输入密码并智能通过验证 将根据表格内容自动填写商品信息完成聚划算活动报名 并支持多款商品上传
  • 又是沙雕的一天-------关于错误关掉任务管理器之后出现的开机黑屏的解决

    沙雕经过 肝了一下午的实验 然后脑子十分不清醒的我 看着自己电脑上N多的窗口 默默的任务栏 gt 右键 gt 任务管理器 gt 任务管理器 gt 结束任务 然后华丽丽的让电脑黑屏了 想起社团大佬的教诲 默默的强制关机 好使 接着登陆界面出现
  • C++11:std::move和std::forward

    标准库函数 std move 既然编译器只对右值引用才能调用转移构造函数和转移赋值函数 而所有的命名对象都只能是左值引用 如果已知一个命名对象不再被使用而想对他调用转移构造函数和转移赋值函数 也就是把一个左值引用当做右值引用来使用 怎么做呢
  • 异步通信起始位正确检测的VHDL实现

    异步通信起始位正确检测的VHDL实现
  • apache做反向代理服务器

    http yahoon blog 51cto com 13184 162922 原创作品 允许转载 转载时请务必以超链接形式标明文章 原始出处 作者信息和本声明 否则将追究法律责任 http yahoon blog 51cto com 13
  • 游戏开发unity杂项知识系列:unity可以使用的小技巧

    插眼 总结 个人觉得这些技巧都挺实用的 参考 Unity3d 提升开发效率的小技巧 第一集 哔哩哔哩 bilibili 一共有五集 这是第一集
  • vue项目中获取今天,昨天,明天时间方法

    在项目中有这个需求 就是在时间查询条件了中 需要默认前天的时间 如果你项目中需要使用今天 昨天 明天时间方法同样适用 具体方法如下 1 vue调用说明 比如我是需要前天的时间 this getDay 2 这个是不包括时分秒的 更多例子如下
  • springMVC中两种validation的简单使用

    本文转自 http elf8848 iteye com blog 1299587 Spring 基于注释的校验机制 1 支持JSR303 Bean Validation定义的校验规范 2 支持Spring框架定义的Validator接口定义