SpringMVC学习记录--Validator验证分析
来源:互联网 发布:docker 阿里云 编辑:程序博客网 时间:2024/06/08 04:50
一.基于Validator接口的验证.
首先创建User实例,并加入几个属性
<code
class
=
"hljs cs"
>
public
class
User {
private
String username;
private
String password;
private
String nickname;
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 getNickname() {
return
nickname;
}
public
void
setNickname(String nickname) {
this
.nickname = nickname;
}
@Override
public
String toString() {
return
"username--"
+username+
"password--"
+password+
"nickname--"
+nickname;
}
}</code>
接着创建用于校检的类UserValidator,让其实现Validator,覆盖其中的两个方法
<code
class
=
"hljs java"
>
import
main.java.model.User;
import
org.springframework.validation.Errors;
import
org.springframework.validation.Validator;
public
class
UserValidator
implements
Validator {
@Override
public
boolean
supports(Class aClass) {
//判断是否是要校验的类,这里是User
return
User.
class
.equals(aClass);
}
@Override
public
void
validate(Object o, Errors errors) {
User u = (User) o;
if
(
null
== u.getPassword() ||
""
.equals(u.getPassword())){
//此方法可以加四个参数,第一个表单域field,
//区分是哪个表单出错,第二个errorCode错误码,
//第三个制定了资源文件中占位符,第四个具体错误返回信息
//简写版可以把2,3参数去掉
errors.rejectValue(
"password"
,
null
,
null
,
"password is null"
);
}
}
}</code>
上面的类只实现了对密码判断是否为空,为空则注册这一错误信息,也就是”password is null”,接下来要实现控制器,控制器要做的事情,第一是注册这个校验器,第二是实现校验.
<code
class
=
"hljs java"
>
import
main.java.model.User;
......
/**
* 加上@Controller决定这个类是一个控制器
*/
@Controller
@RequestMapping
(
"/user"
)
public
class
HelloController {
//我们知道在Controller类中通过@InitBinder标记的方法只有在请求当前Controller的时候才会被执行
//所以在这里注册校验器
@InitBinder
public
void
initBainder(DataBinder binder){
binder.replaceValidators(
new
UserValidator());
}
//这个方法主要是跳转到登录页面
@RequestMapping
(value =
"/login"
,method = RequestMethod.GET)
public
String login(Model model){
model.addAttribute(
new
User());
return
"user/login"
;
}
//处理登录表单
@RequestMapping
(value =
"/login"
,method = RequestMethod.POST)
public
String login(
@Validated
User user, BindingResult br){
if
(br.hasErrors()){
return
"user/login"
;
}
return
"--"
;
}
}</code>
上面代码可以看到@Validated User user, BindingResult br这两个参数,@Validated表明参数user是要校验的类,BindingResult是存储错误信息的类,两者必须一一对应,并且位置挨着,不能中间有其他参数,
最后随便写一个jsp页面实现校检
<code
class
=
"hljs xml"
><%@ contenttype=
"text/html;charset=UTF-8"
language=
"java"
page=
""
>
<%
@taglib
prefix=
"sf"
uri=
"http://www.springframework.org/tags/form"
>
<%>
<sf:form method=
"post"
modelattribute=
"user"
>
用户名:<sf:input path=
"username"
></sf:input><sf:errors path=
"username"
></sf:errors>
密码:<sf:input path=
"password"
></sf:input><sf:errors path=
"password"
></sf:errors>
昵称:<sf:input path=
"nickname"
></sf:input><sf:errors path=
"nickname"
></sf:errors>
<input type=
"submit"
value=
"提交"
>
</sf:form></code>
前面实现的是局部校验,只对当前控制器有效,如果要实现全局校验的话需要配置springMVC.xml文件
<code
class
=
"hljs xml"
>
<beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:context=
"http://www.springframework.org/schema/context"
xmlns:mvc=
"http://www.springframework.org/schema/mvc"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemalocation="http://www.springframework.org/schema/beans
http:
//www.springframework.org/schema/beans/spring-beans-3.0.xsd
http:
//www.springframework.org/schema/context
http:
//www.springframework.org/schema/context/spring-context-3.0.xsd
http:
//www.springframework.org/schema/mvc
http:
//www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven validator=
"userValidator"
></mvc:annotation-driven>
<bean
class
=
"com.xxx.xxx.UserValidator"
id=
"userValidator"
></bean>
...
</beans></code>
二.使用Annotaion JSR-303标准的验证
使用这个需要导入支持JSR-303标准的包,建议使用Hibernate Validator这个包,先看这个标准的原生标注
要使用很简单,在需要验证的变量前面加上该Annotation即可,看下面使用后的User
<code
class
=
"hljs java"
>
public
class
User {
@NotEmpty
(message =
"用户名不能为空"
)
private
String username;
@Size
(min=
6
,max=
20
,message =
"密码长度不符合标准"
)
private
String password;
private
String nickname;
......
}</code>
然后再控制器里面加入验证就可以了
<code
class
=
"hljs java"
>
@Controller
@RequestMapping
(
"/user"
)
public
class
HelloController {
@RequestMapping
(value =
"/login"
,method = RequestMethod.GET)
public
String login(Model model){
model.addAttribute(
new
User());
return
"user/login"
;
}
@RequestMapping
(value =
"/login"
,method = RequestMethod.POST)
public
String login(
@Validated
User user, BindingResult br){
if
(br.hasErrors()){
return
"user/login"
;
}
return
"user/login"
;
}
}</code>
然后jsp页面还是之前的页面,验证效果如下,这种方法明显简单多了
3.定义自己的Annotation Validator
这部分直接从大牛那拷贝过来的.
除了JSR-303原生支持的限制类型之外我们还可以定义自己的限制类型。定义自己的限制类型首先我们得定义一个该种限制类型的注解,而且该注解需要使用@Constraint标注。现在假设我们需要定义一个表示金额的限制类型,那么我们可以这样定义:
<code
class
=
"hljs avrasm"
>
import
java.lang.annotation.ElementType;
import
java.lang.annotation.Retention;
import
java.lang.annotation.RetentionPolicy;
import
java.lang.annotation.Target;
import
javax.validation.Constraint;
import
javax.validation.Payload;
import
com.xxx.xxx.constraint.impl.MoneyValidator;
@Target
({ElementType.FIELD, ElementType.METHOD})
@Retention
(RetentionPolicy.RUNTIME)
@Constraint
(validatedBy=MoneyValidator.
class
)
public
@interface
Money {
String message()
default
"不是金额形式"
;
Class[] groups()
default
{};
Class[] payload()
default
{};
}</code>
我们可以看到在上面代码中我们定义了一个Money注解,而且该注解上标注了@Constraint注解,使用@Constraint注解标注表明我们定义了一个用于限制的注解。@Constraint注解的validatedBy属性用于指定我们定义的当前限制类型需要被哪个ConstraintValidator进行校验。在上面代码中我们指定了Money限制类型的校验类是MoneyValidator。另外需要注意的是我们在定义自己的限制类型的注解时有三个属性是必须定义的,如上面代码所示的message、groups和payload属性。
在定义了限制类型Money之后,接下来就是定义我们的限制类型校验类MoneyValidator了。限制类型校验类必须实现接口javax.validation.ConstraintValidator,并实现它的initialize和isValid方法。我们先来看一下MoneyValidator的代码示例:
<code
class
=
"hljs axapta"
>
import
java.util.regex.Pattern;
import
javax.validation.ConstraintValidator;
import
javax.validation.ConstraintValidatorContext;
import
com.xxx.xxx.constraint.Money;
public
class
MoneyValidator
implements
ConstraintValidator {
private
String moneyReg =
"^\\d+(\\.\\d{1,2})?$"
;
//表示金额的正则表达式
private
Pattern moneyPattern = Pattern.compile(moneyReg);
public
void
initialize(Money money) {
// TODO Auto-generated method stub
}
public
boolean
isValid(Double value, ConstraintValidatorContext arg1) {
// TODO Auto-generated method stub
if
(value ==
null
)
return
true
;
return
moneyPattern.matcher(value.toString()).matches();
}
}</code>
从上面代码中我们可以看到ConstraintValidator是使用了泛型的。它一共需要指定两种类型,第一个类型是对应的initialize方法的参数类型,第二个类型是对应的isValid方法的第一个参数类型。从上面的两个方法我们可以看出isValid方法是用于进行校验的,有时候我们在校验的过程中是需要取当前的限制类型的属性来进行校验的,比如我们在对@Min限制类型进行校验的时候我们是需要通过其value属性获取到当前校验类型定义的最小值的,我们可以看到isValid方法无法获取到当前的限制类型Money。这个时候initialize方法的作用就出来了。我们知道initialize方法是可以获取到当前的限制类型的,所以当我们在校验某种限制类型时需要获取当前限制类型的某种属性的时候,我们可以给当前的ConstraintValidator定义对应的属性,然后在initialize方法中给该属性赋值,接下来我们就可以在isValid方法中使用其对应的属性了。针对于这种情况我们来看一个代码示例,现在假设我要定义自己的@Min限制类型和对应的MinValidator校验器,那么我可以如下定义:
<code
class
=
"hljs handlebars"
>
@Target
({ElementType.FIELD, ElementType.METHOD})
@Retention
(RetentionPolicy.RUNTIME)
@Constraint
(validatedBy=MinValidator.
class
)
public
@interface
Min {
int
value()
default
0
;
String message();
Class[] groups()
default
{};
Class[] payload()
default
{};
}</code>
MinValidator校验器
<code
class
=
"hljs axapta"
>
public
class
MinValidator
implements
ConstraintValidator {
private
int
minValue;
public
void
initialize(Min min) {
// TODO Auto-generated method stub
//把Min限制类型的属性value赋值给当前ConstraintValidator的成员变量minValue
minValue = min.value();
}
public
boolean
isValid(Integer value, ConstraintValidatorContext arg1) {
// TODO Auto-generated method stub
//在这里我们就可以通过当前ConstraintValidator的成员变量minValue访问到当前限制类型Min的value属性了
return
value >= minValue;
}
}</code>
继续来说一下ConstraintValidator泛型的第二个类型,我们已经知道它的第二个类型是对应的isValid的方法的第一个参数,从我给的参数名称value来看也可以知道isValid方法的第一个参数正是对应的当前需要校验的数据的值,而它的类型也正是对应的我们需要校验的数据的数据类型。这两者的数据类型必须保持一致,否则Spring会提示找不到对应数据类型的ConstraintValidator。建立了自己的限制类型及其对应的ConstraintValidator后,其用法跟标准的JSR-303限制类型是一样的。以下就是使用了上述自己定义的JSR-303限制类型——Money限制和Min限制的一个实体类:
<code
class
=
"hljs cs"
>
public
class
User {
private
int
age;
private
Double salary;
@Min
(value=
8
, message=
"年龄不能小于8岁"
)
public
int
getAge() {
return
age;
}
public
void
setAge(
int
age) {
this
.age = age;
}
@Money
(message=
"标准的金额形式为xxx.xx"
)
public
Double getSalary() {
return
salary;
}
public
void
setSalary(Double salary) {
this
.salary = salary;
}
}</code>
- SpringMVC学习记录--Validator验证分析
- SpringMVC学习记录(六)--Validator验证
- SpringMVC学习记录(六)--Validator验证
- SpringMVC学习记录(六)--Validator验证
- SpringMVC学习记录(六)--Validator验证
- SpringMVC学习之验证——validator
- springmvc validator验证的使用
- springmvc validator验证的使用
- springmvc validator验证的使用
- springmvc validator验证的使用
- springmvc:Validator数据有效性验证
- 使用Validator做SpringMVC的验证框架 - Validator前端验证
- 学习笔记(二) springmvc+validator校验中的组合验证和顺序验证
- 使用Validator做SpringMVC的验证框架 - 使用Validator
- SpringMVC学习系列-后记 结合SpringMVC和Hibernate-validator,根据后台验证规则自动生成前台的js验证代码
- springMVC Hibernate Validator验证框架的使用
- SpringMVC 之validator验证笔记(五)
- 使用Validator做SpringMVC的验证框架 - 配置SpringMVC环境
- 用ffmpeg 把mp4文件转为ts文件并生成m3u8列表
- Android_注解与泛型
- Prism框架(二)——Prism应用程序初始化
- 手机端的下拉刷新和上拉加载
- 图解TCP/IP 读后感
- SpringMVC学习记录--Validator验证分析
- git的常用命令
- 什么是java序列化,如何实现java序列化?
- 简单背包问题
- Prism框架(三)——基于模块的应用程序开发
- 编译,反编译,混淆,【一】
- 我在学校网站一页面上无意间发现了一个漏洞
- 大数据学习2——大数据处理架构Hadoop概述
- 【Python】选择ipython替代python的理由