如何使用SpringMVC进行数据校验

前言:

SpringMVC数据校验采用JSR-303校验。

• Spring 4.0 拥有自己独立的数据校验框架,同时支持 JSR
303 标准的校验框架。
• Spring 在进行数据绑定时,可同时调用校验框架完成数据校
验工作。在 Spring MVC 中,可直接通过注解驱动的方式
进行数据校验
• Spring 的 LocalValidatorFactroyBean 既实现了 Spring 的
Validator 接口,也实现了 JSR 303 的 Validator 接口。只要
在 Spring 容器中定义了一个
LocalValidatorFactoryBean,即可将其注入到需要数据校
验的 Bean 中。
Spring 本身并没有提供 JSR303 的实现,所以必须将
JSR303 的实现者的 jar 包放到类路径下

Hibernate Validator 是 JSR 303 的一个参考实现,这里我们就采用Hibernate validator。

JSR-303校验说明:

1.@NotNull/@Null        
  验证字段: 引用数据类型      
  注解说明:注解元素必须是非空或空
2.@Digits
  验证字段:byte、short、int、long及各自的包装类型以及BigDecimal、BigInteger、String
  注解说明:验证数字构成是否合法
  属性说明:integer:指定整数部分数字位数,fraction:指定小数部分数字位数
3.@Future/Past
  验证字段:java.util.Date,java.util.Calendar
  注解说明:验证是否在当前系统时间之后/之前
4.@Max/@Min
  验证字段:byte、short、int、long及对应的包装类型以及BigDecimal、BigInteger
  注解说明:验证值是否小于等于最大指定整数值或大于等于最小指定整数值
5.@Pattern
  验证字段:String
  注解说明:验证字符串是否匹配指定的正则表达式
  属性说明:regexp:匹配的正则表达式,flags:指定Pattern.Flag的数值,表示正则表达式的选项
6.@Size
  验证字段:String、Collection、Map和数组
  注解说明:验证元素大小是否在指定范围内
  属性说明:max:最大长度,min:最小长度,message:提示信息,默认:{constraint.size}
7.@DecimalMax/@DecimalMin
  验证字段:byte、short、int、long及对应的包装类型以及BigDecimal、BigInteger、String
  属性说明:验证值是否小于等于最大指定小数值或大于等于最小指定小数值
8.@Valid
  属性说明:验证值是否需要递归调用

Hibernate Validator增加了一些校验规则:

1.@Email  被注释的元素必须是电子邮箱地址
2.@Length          被注释的字符串的大小必须在指定的范围内
3.@NotEmpty  被注释的字符串的必须非空
4.@Range          被注释的元素必须在合适的范围内
 

一,准备Jar包:

使用Maven导入jar包:

<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.2.4.Final</version>
        </dependency>

二,校验示例:

JavaBean:

public class Student implements Serializable {
    @DecimalMin("10")
    private Long sid;
    @NotNull
    @Pattern(regexp = "b.*")
    private String name;
    @Past
    @JsonSerialize(using = CustomDateSerializer.class)
    private Date birthday;

    public Long getSid() {
        return sid;
    }

    public void setSid(Long sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

 

为了在校验和数据转换失败时输出我们自定义的错误信息,我们需要配置国际化资源文件:

i18n.properties:

#校验注解名.类名全小写.类中的属性=xxxxx 表示进行JSR-303注解校验失败时使用的国际化信息
DecimalMin.student.sid=ID必须大于10喔^-^
NotNull.student.name=名字不能为空喔
Pattern.student.name=名字必须以b开头喔
Past.student.birthday=亲,您是穿越了嘛!
#[typeMismatch|required|methodInvocation].类名全小写.类中属性=xxxxx 表示在类型转换失败时使用的国际化信息
typeMismatch.student.birthday=您输入的是一个日期嘛,亲!

配置SpringMVC,

 <!--注册国际化资源文件-->
    <bean id = "messageSource" class = "org.springframework.context.support.ResourceBundleMessageSource">
        <property name = "basename" value = "i18n" />
        <property name = "defaultEncoding" value="GBK"/>
    </bean>

测试方法如下:

@RequestMapping("testvalid")
    public String TestValid(
            @Valid//如果需要校验则需要驾驶@Valid注解
            @ModelAttribute("student")
                    Student student,
            Errors errors, Map<String, Object> map) {
        System.out.println(student);
        if (errors.hasErrors()) {
            System.out.println("这里有一些错误");
            for (FieldError fieldError :
                    errors.getFieldErrors()) {
                System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage());

            }
            return "forward:/input.jsp";
        }
        map.put("msg", "转换并校验成功了!");
        return "success";
    }

Jsp文件如下:


<!DOCTYPE html>
<html lang = "en">
<head>
    <base href = "<%=basePath %>" />
    <meta charset = "UTF-8">
    <title></title>
</head>
<style>
    span {
        color: red;
    }
</style>
<body>
    <form:errors path = "student.*" />
    <form action = "hello/testvalid.do" method = "post">
        ID:<input type = "text" name = "sid" value = "${student.sid}" />
        <form:errors path = "student.sid" />
        <br />
        Name:<input type = "text" name = "name" value = "${student.name}" />
        <form:errors path = "student.name" />
        <br />
        Birthday:<input type = "text" name = "birthday"
                        value = "<fmt:formatDate value="${student.birthday}" pattern="yyyy-MM-dd"/>" />
        <form:errors path = "student.birthday" />
        <br />

        <input type = "submit" value = "Commit" />
    </form>
</body>
</html>

测试结果如下:

195346_6TMB_2608182.png

195417_wYr9_2608182.png

Tips:

• <mvc:annotation-driven/> 会默认装配好一个
LocalValidatorFactoryBean,通过在处理方法的入参上标
@valid 注解即可让 Spring MVC 在完成数据绑定后执行
数据校验的工作
• 在已经标注了 JSR303 注解的表单/命令对象前标注一个
@Valid,Spring MVC 框架在将请求参数绑定到该入参对象
后,就会调用校验框架根据注解声明的校验规则实施校验
• Spring MVC 是通过对处理方法签名的规约来保存校验结果
的:前一个表单/命令对象的校验结果保存到随后的入参
中,这个保存校验结果的入参必须是 BindingResult
Errors 类型,这两个类都位于
org.springframework.validation 包中
• 需校验的 Bean 对象和其绑定结果对象或错误对象时成对出现的,它们
之间不允许声明其他的入参

• Errors 接口提供了获取错误信息的方法,如 getErrorCount() 或
getFieldErrors(String field)
• BindingResult 扩展了 Errors 接口
195724_XS27_2608182.png

• 在表单/命令对象类的属性中标注校验注解,在处理方法对
应的入参前添加 @Valid,Spring MVC 就会实施校验并将校
验结果保存在被校验入参对象之后的 BindingResult 或
Errors 入参中。
• 常用方法:
FieldError getFieldError(String field)
List<FieldError> getFieldErrors()
Object getFieldValue(String field)
Int getErrorCount()
• Spring MVC 除了会将表单/命令对象的校验结果保存到对
应的 BindingResult 或 Errors 对象中外,还会将所有校验
结果保存到 隐含模型
• 即使处理方法的签名中没有对应于表单/命令对象的结果
入参,校验结果也会保存在 “隐含对象” 中。
• 隐含模型中的所有数据最终将通过 HttpServletRequest 的
属性列表暴露给 JSP 视图对象,因此在 JSP 中可以获取
错误信息
• 在 JSP 页面上可通过 <form:errors path=“userName”>
显示错误消息
• 每个属性在数据绑定和数据校验发生错误时,都会生成一
个对应的 FieldError 对象。
当一个属性校验失败后,校验框架会为该属性生成 4 个消
息代码,这些代码以校验注解类名为前缀,结合
modleAttribute、属性名及属性类型名生成多个对应的消
息代码:例如 User 类中的 password 属性标准了一个 @Pattern 注
解,当该属性值不满足 @Pattern 所定义的规则时, 就会产生以下 4
个错误代码:
– Pattern.user.password
– Pattern.password
– Pattern.java.lang.String
– Pattern
• 当使用 Spring MVC 标签显示错误消息时, Spring MVC 会查看
WEB 上下文是否装配了对应的国际化消息,如果没有,则显示默认
的错误消息,否则使用国际化消息。
若数据类型转换或数据格式转换时发生错误,或该有的参
数不存在,或调用处理方法时发生错误,都会在隐含模型
中创建错误消息。其错误代码前缀说明如下:
required:必要的参数不存在。如 @RequiredParam(“param1”)
标注了一个入参,但是该参数不存在
typeMismatch:在数据绑定时,发生数据类型不匹配的问题
methodInvocation:Spring MVC 在调用处理方法时发生了错误
 

 

注意:

若你没有使用BindingResult Errors 类型来存储校验失败时的错误信息,则Spring MVC会直接抛出

org.springframework.validation.BindException

异常。所以你可以使用Spring MVC的异常处理来捕获此类异常并获取你配置的校验未通过信息:

215945_Vxgj_2608182.png

 

需要特别注意的是:以上@Valid注解在了没有使用@RequestBody注解的参数上,

若@Valid注解在了使用@RequestBody注解的参数上(即参数对象通过Json字符串反序列化生成),倘若校验未通过将会抛出org.springframework.web.bind.MethodArgumentNotValidException异常,你同样可以捕获该异常:

190121_BgAa_2608182.png

关于使用Spring MVC的异常处理请参考博客:

https://my.oschina.net/u/2608182/blog/741733

 

转载请注明出处

转载于:https://my.oschina.net/u/2608182/blog/741198

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值