005-Spring MVC参数验证1

服务器端的数据验证,对于一个WEB应用来说是非常重要的。现在前后端分离的请求来说,一般是前端验证后,直接调用后端接口,将数据传入后端处理。如果直接调用接口,那么数据就没有通过验证,这是危险的或者说后端得到的数据是不可控的。所以后端验证是必要的。

Spring Boot中引入验证依赖

        <!-- Spring boot添加验证支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

Spring中提供了hibernate-validator的适配,其实最终就是用的hibernate-validator。

验证类

Spring 支持Hibernate Validator提供的各类验证注解。验证类的编写如下

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

public class UserDTO {

    @NotNull
    private String name;

    @NotNull
    @Min(message = "年龄不能小于{value}岁",value = 10) 
    @Max(message = "{message.ValidTestBean.age.max}",value = 150) 
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

message属性可以不用设置,在不设置的情况下,其将使用默认的消息。(查看@NotNull的源码你可以发现其配置的默认消息配置)

message属性中可以使用{value}来引用value属性的值,spring在返回信息的时候会自动替换

message属性可以使用国际化配置属性,如我们示例中的{message.ValidTestBean.age.max}。当然要使用我们自定义的国际化配置文件需要一些设置。这个我们后面再说。

DTO:data Transfer Object,数据传输对象,可以认为就是前端参数在后端的表示。

Controller参数验证代码

import com.yyoo.springmvc.bean.dto.UserDTO;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

@RestController
@RequestMapping("validate")
public class Demo3Controller {

    @RequestMapping("test1")
    public void test1(@RequestBody @Valid UserDTO bean, BindingResult errors){

        System.out.println(errors.hasErrors()+"======hasErrors");
        System.out.println(errors.hasFieldErrors()+"=====fieldErrors");

        for(FieldError error : errors.getFieldErrors()){
            System.out.println("验证的字段名称:"+error.getField());
            System.out.println("验证规则名称:" + error.getCode());
            System.out.println("提示信息:" + error.getDefaultMessage());
            System.out.println("参数名称:" + error.getObjectName());
            for(Object obj : error.getArguments()){
                System.out.println("=======" + obj);
            }
            for(String str : error.getCodes()){
                System.out.println("+++++++"+str);
            }
        }

    }

}

注意:BindingResult 参数必须紧跟我们要验证的参数,中间不能有其他参数隔开,否则BindingResult 对象无法获得验证信息。

示例中我们只是遍历了对应的错误认证信息,实际使用中我们需要把我们需要的信息返回给前端处理显示。

国际化支持

示例中@NotNull,的提示信息为:“不能为null”,这个默认的提示信息是在hibernate-validator-x.x.x.Final.jar包中定义的,国际化配置文件的名称为:ValidationMessages,那么我们是中文环境使用的默认国际化配置为ValidationMessages_zh_CN.properties。其定义如下:

javax.validation.constraints.AssertFalse.message     = 只能为false
javax.validation.constraints.AssertTrue.message      = 只能为true
javax.validation.constraints.DecimalMax.message      = 必须小于${inclusive == true ? '或等于' : ''}{value}
javax.validation.constraints.DecimalMin.message      = 必须大于${inclusive == true ? '或等于' : ''}{value}
javax.validation.constraints.Digits.message          = 数字的值超出了允许范围(只允许在{integer}位整数和{fraction}位小数范围内)
javax.validation.constraints.Email.message           = 不是一个合法的电子邮件地址
javax.validation.constraints.Future.message          = 需要是一个将来的时间
javax.validation.constraints.FutureOrPresent.message = 需要是一个将来或现在的时间
javax.validation.constraints.Max.message             = 最大不能超过{value}
javax.validation.constraints.Min.message             = 最小不能小于{value}
javax.validation.constraints.Negative.message        = 必须是负数
javax.validation.constraints.NegativeOrZero.message  = 必须是负数或零
javax.validation.constraints.NotBlank.message        = 不能为空
javax.validation.constraints.NotEmpty.message        = 不能为空
javax.validation.constraints.NotNull.message         = 不能为null
javax.validation.constraints.Null.message            = 必须为null
javax.validation.constraints.Past.message            = 需要是一个过去的时间
javax.validation.constraints.PastOrPresent.message   = 需要是一个过去或现在的时间
javax.validation.constraints.Pattern.message         = 需要匹配正则表达式"{regexp}"
javax.validation.constraints.Positive.message        = 必须是正数
javax.validation.constraints.PositiveOrZero.message  = 必须是正数或零
javax.validation.constraints.Size.message            = 个数必须在{min}和{max}之间

org.hibernate.validator.constraints.CreditCardNumber.message        = 不合法的信用卡号码
org.hibernate.validator.constraints.Currency.message                = 不合法的货币 (必须是{value}其中之一)
org.hibernate.validator.constraints.EAN.message                     = 不合法的{type}条形码
org.hibernate.validator.constraints.Email.message                   = 不是一个合法的电子邮件地址
org.hibernate.validator.constraints.Length.message                  = 长度需要在{min}和{max}之间
org.hibernate.validator.constraints.CodePointLength.message         = 长度需要在{min}和{max}之间
org.hibernate.validator.constraints.LuhnCheck.message               = ${validatedValue}的校验码不合法, Luhn模10校验和不匹配
org.hibernate.validator.constraints.Mod10Check.message              = ${validatedValue}的校验码不合法, 模10校验和不匹配
org.hibernate.validator.constraints.Mod11Check.message              = ${validatedValue}的校验码不合法, 模11校验和不匹配
org.hibernate.validator.constraints.ModCheck.message                = ${validatedValue}的校验码不合法, {modType}校验和不匹配
org.hibernate.validator.constraints.NotBlank.message                = 不能为空
org.hibernate.validator.constraints.NotEmpty.message                = 不能为空
org.hibernate.validator.constraints.ParametersScriptAssert.message  = 执行脚本表达式"{script}"没有返回期望结果
org.hibernate.validator.constraints.Range.message                   = 需要在{min}和{max}之间
org.hibernate.validator.constraints.ScriptAssert.message            = 执行脚本表达式"{script}"没有返回期望结果
org.hibernate.validator.constraints.URL.message                     = 需要是一个合法的URL

org.hibernate.validator.constraints.time.DurationMax.message        = 必须小于${inclusive == true ? '或等于' : ''}${days == 0 ? '' : days += '天'}${hours == 0 ? '' : hours += '小时'}${minutes == 0 ? '' : minutes += '分钟'}${seconds == 0 ? '' : seconds += '秒'}${millis == 0 ? '' : millis += '毫秒'}${nanos == 0 ? '' : nanos += '纳秒'}
org.hibernate.validator.constraints.time.DurationMin.message        = 必须大于${inclusive == true ? '或等于' : ''}${days == 0 ? '' : days += '天'}${hours == 0 ? '' : hours += '小时'}${minutes == 0 ? '' : minutes += '分钟'}${seconds == 0 ? '' : seconds += '秒'}${millis == 0 ? '' : millis += '毫秒'}${nanos == 0 ? '' : nanos += '纳秒'}

自定义国际化文件

简单的方式实现自定义国际化的方式是,拷贝ValidationMessages对应的properties文件,不要修改文件名称,然后在配置文件中添加自己的配置即可。但如果我们要自定义国际化文件的名称,在配置类中如下配置:

    @Bean
    public static LocalValidatorFactoryBean getLocalValidatorFactoryBean() {
        LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
        // 如果你需要在其他地方用到该messageSource,可以将它在容器中声明
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasenames("message");// i18n文件的名称
        messageSource.setDefaultLocale(Locale.CHINA);// 默认语言,如果不设置则为当前系统的语言(建议设置)
        factoryBean.setValidationMessageSource(messageSource);

        return factoryBean;
    }

LocalValidatorFactoryBean 是提供验证相关配置的基础类。

Hibernate Validate下的验证注解

验证注解验证的数据类型说明
@AssertFalseBoolean,boolean验证注解的元素值是false
@AssertTrueBoolean,boolean验证注解的元素值是true
@NotNull任意类型验证注解的元素值不是null
@Null任意类型验证注解的元素值是null
@Min(value=值)BigDecimal,BigInteger, byte,short, int, long,等任何Number或CharSequence(存储的是数字)子类型验证注解的元素值大于等于@Min指定的value值
@Max(value=值)和@Min要求一样验证注解的元素值小于等于@Max指定的value值
@DecimalMin(value=值)和@Min要求一样验证注解的元素值大于等于@ DecimalMin指定的value值
@DecimalMax(value=值)和@Min要求一样验证注解的元素值小于等于@ DecimalMax指定的value值
@Digits(integer=整数位数, fraction=小数位数)和@Min要求一样验证注解的元素值的整数位数和小数位数上限
@Size(min=下限, max=上限)字符串、Collection、Map、数组等验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小
@Pastjava.util.Date,java.util.Calendar;Joda Time类库的日期类型验证注解的元素值(日期类型)比当前时间早
@Future与@Past要求一样验证注解的元素值(日期类型)比当前时间晚
@NotBlankCharSequence子类型验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的首位空格
@Length(min=下限, max=上限)CharSequence子类型验证注解的元素值长度在min和max区间内
@NotEmptyCharSequence子类型、Collection、Map、数组验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
@Range(min=最小值, max=最大值)BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子类型和包装类型验证注解的元素值在最小值和最大值之间
@Email(regexp=正则表达式,flag=标志的模式)CharSequence子类型(如String)验证注解的元素值是Email,也可以通过regexp和flag指定自定义的email格式
@Pattern(regexp=正则表达式,flag=标志的模式)String,任何CharSequence的子类型验证注解的元素值与指定的正则表达式匹配
@Valid任何非原子类型,指定递归验证关联的对象;作用在接收参数上,表示该参数需要验证。在参数对象中包含其他对象,可以使用该注解表示需要级联验证。这个我们下一篇文章来详细讲解。

上一篇:004-Spring MVC参数类型转换
下一篇:006-Spring MVC参数验证2-分组验证

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值