您的位置:首页 > 其它

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="*" />来显示。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: