MVC 表单验证
2014-10-09 10:44
134 查看
表单:
用户注册页面: 名称:user.jsp
注册用户包含三项信息: 用户名,密码,邮箱。
[html]
view plain
copy
<
%@ 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
>
校验方式一: JSR303 Bean Validation
在Spring3.1中增加的了对JSR303 Bean Validation规范的支持,不仅可以对Spring的 MVC进行校验,而且也可以对Hibernate的存储对象进行校验。是一个通用的校验框架。
环境准备:
A) 导入Hibernate-Validator
要使用JSR303 校验框架, 需要加入框架的具体实现Hibernate-Validator, 在soureforge上下载最新的Hibernate-Validator
, 当前版本为4.2.0 Final版。
在/WEB-INF/lib中导入 hibernate-validator-4.2.0.Final.jar, hibernate-validator-annotation-processor-4.2.0.Final.jar, 导入它的lib/required目录下内容slf4j-api-1.6.1.jar, validation-api-1.0.0.GA.jar;
B) 配置Spring对JSR 303 的支持。
在你的 <servletName>-servlet.xml配置文件中,使用标签:
[html]
view plain
copy
<
mvc:annotation-driven
/>
配置对JSR303的支持,包括制动查找Hibernate-Validator的实现等工作。
1) 可用的
JSR303注解
空检查
@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=) Validates that the annotated string is between min and max included.
日期检查
@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对象如下:
[java]
view plain
copy
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();
}
}
2) Validate的触发
在需要校验的对象前增加 @Valid 注解 (该注解位于javax.validation包中)来触发校验。示例如下:
[java]
view plain
copy
/**
* 处理提交的用户注册信息。
* @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
1)Validator接口的实现:
Spring框架的Validator接口定义,
[java]
view plain
copy
package
org.springframework.validation;
public
interface
Validator {
boolean
supports(Class<?> clazz);
void
validate(Object target, Errors errors);
}
要使用它进行校验必须实现该接口。实现Validator接口的代码如下:
[java]
view plain
copy
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"
,
"邮箱格式错误"
);
}
}
}
2) 设置Validator,并触发校验。
在我们的Controller中需要使用父类已有的方法来为DataBinder对象指定Validator, protected initBinder(WebDataBinder binder); 代码如下:
[java]
view plain
copy
@InitBinder
protected
void
initBinder(WebDataBinder binder){
binder.setValidator(new
UserValidator());
}
为binder对象指定好Validator校验对象后,下面一步的就是在需要校验的时候触发validate方法,该触发步骤是通过 @Validated 注解(该注解是Spring框架定义的)实现的。
[java]
view plain
copy
/**
* 处理提交的用户注册信息。
* @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="*" />来显示。
用户注册页面: 名称:user.jsp
注册用户包含三项信息: 用户名,密码,邮箱。
[html]
view plain
copy
<
%@ 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
>
校验方式一: JSR303 Bean Validation
在Spring3.1中增加的了对JSR303 Bean Validation规范的支持,不仅可以对Spring的 MVC进行校验,而且也可以对Hibernate的存储对象进行校验。是一个通用的校验框架。
环境准备:
A) 导入Hibernate-Validator
要使用JSR303 校验框架, 需要加入框架的具体实现Hibernate-Validator, 在soureforge上下载最新的Hibernate-Validator
, 当前版本为4.2.0 Final版。
在/WEB-INF/lib中导入 hibernate-validator-4.2.0.Final.jar, hibernate-validator-annotation-processor-4.2.0.Final.jar, 导入它的lib/required目录下内容slf4j-api-1.6.1.jar, validation-api-1.0.0.GA.jar;
B) 配置Spring对JSR 303 的支持。
在你的 <servletName>-servlet.xml配置文件中,使用标签:
[html]
view plain
copy
<
mvc:annotation-driven
/>
配置对JSR303的支持,包括制动查找Hibernate-Validator的实现等工作。
1) 可用的
JSR303注解
空检查
@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=) Validates that the annotated string is between min and max included.
日期检查
@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信用卡验证
验证是否是邮件地址,如果为null,不进行验证,算通过验证。
@ScriptAssert(lang= ,script=, alias=)
@URL(protocol=,host=, port=,regexp=, flags=)
通过上述Constraint约束后的User对象如下:
[java]
view plain
copy
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();
}
}
2) Validate的触发
在需要校验的对象前增加 @Valid 注解 (该注解位于javax.validation包中)来触发校验。示例如下:
[java]
view plain
copy
/**
* 处理提交的用户注册信息。
* @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
1)Validator接口的实现:
Spring框架的Validator接口定义,
[java]
view plain
copy
package
org.springframework.validation;
public
interface
Validator {
boolean
supports(Class<?> clazz);
void
validate(Object target, Errors errors);
}
要使用它进行校验必须实现该接口。实现Validator接口的代码如下:
[java]
view plain
copy
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"
,
"邮箱格式错误"
);
}
}
}
2) 设置Validator,并触发校验。
在我们的Controller中需要使用父类已有的方法来为DataBinder对象指定Validator, protected initBinder(WebDataBinder binder); 代码如下:
[java]
view plain
copy
@InitBinder
protected
void
initBinder(WebDataBinder binder){
binder.setValidator(new
UserValidator());
}
为binder对象指定好Validator校验对象后,下面一步的就是在需要校验的时候触发validate方法,该触发步骤是通过 @Validated 注解(该注解是Spring框架定义的)实现的。
[java]
view plain
copy
/**
* 处理提交的用户注册信息。
* @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="*" />来显示。
相关文章推荐
- Asp.Net MVC杂谈之:—步步打造表单验证框架[重排版](1)
- sp.net MVC&JQuery 应用(表单验证)
- 详解ASP.NET MVC Form表单验证
- 【转】ASP.NET MVC 3.0 表单验证 - ASP.NET MVC 3 Remote Validation
- Spring-Mvc之表单验证的两种方式-yellowcong
- ASP.NET MVC Jquery Validate 表单验证的多种方式
- asp.net MVC&JQuery 应用(表单验证)
- HTML5中custom data-*特性与asp.net mvc 3 表单验证
- ASP.NET MVC 4 (十三) 基于表单的身份验证
- ASP.NET MVC异步验证是如何工作的02,异步验证表单元素的创建
- MVC 表单验证的几种方式:
- springMVC+freeMarker表单验证
- spring mvc + 表单异步验证插件 Validate.form.js
- 在MVC中验证表单数据
- MVC中通用JS判断表单或者某个具体的文本框验证是否通过
- ValidationSugar表单验证框架-支持ASP.NET MVC ASP.NET WebFroM
- Spring MVC快速教程:表单验证 Spring MVC Fast Tutorial: Form Validation
- ASP.NET MVC 表单验证方式总结
- 【转】asp.net MVC&JQuery 应用(表单验证)
- ASP.NET MVC 客户端验证失败后表单仍然提交问题