Hibernate-invalidator校验

一、参数校验(类属性)

在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等。 会导致如下情况:

  • 验证代码繁琐
  • 方法内代码显得冗长
  • 修改相同逻辑验证代码时需要修改涉及到同样逻辑的所有地方

hibernate validator(官方文档)提供了一套比较完善、便捷的验证实现方式。
spring-boot-starter-web 包里面有hibernate-validator包,不需要再引入依赖。
使用@Valid对参数进行校验在使用对象进行参数接收时,我们可以对参数进行校验录入我们可以对属性username和password加上如下注解:

public class User{

    @NotNull(message = "用户名不能为空")
    private String username; // 用户名

    @Max(value = 999999,message = "超过最大数值")
    @Min(value = 000000,message = "密码设定不正确")
    @NotNull(message = "密码不能为空")
    private String password; // 密码
}

然后我们给Controller层的方法中接收的对象前加入@Valid注解,并在参数中加入BindingResult来获取错误信息。
在逻辑处理中我们判断BindingResult知否含有错误信息,如果有错误信息,则直接返回错误信息。

// 添加用户
@PostMapping("/createuser")  // 多个 @Valid 则对应多个 BindingReslt
public String createUser(@Valid User user, BindingResult bindingResult){
    if (bindingResult.hasErrors()){        
        return bindingResult.getFieldError().getDefaultMessage();
    }else{
        userService.createUser(userInfo.getTel(),userInfo.getPassWord(); return "OK";
    }
}

Hibernate validator的校验只能对Object的属性进行校验,不能对单个的参数进行校验,spring 在此基础上进行了扩展,添加了++MethodValidationPostProcessor拦截器++后可以实现对方法参数的校验。

二、参数校验(方法参数)

1 实例化MethodValidationPostProcessor拦截器

@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
    return new MethodValidationPostProcessor();
}

2 在所要实现方法参数校验的类上面添加@Validated,如下

@Validated  // 加入注释
@RestController
@RestMapping("/validate")
public class ValidateController {

3 在方法上面添加校验规则

@GetMapping("/paramcheck")
public String paramCheck(@Length(min = 10) @RequestParam String name) {
    System.out.println(name);
    return null;
}

4 当方法上面的参数校验失败,spring 框架就回抛出异常

{
  "timestamp": 1476108200558,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "javax.validation.ConstraintViolationException",
  "message": "No message available",
  "path": "/paramcheck"
}

三、hibernate的校验模式

通常的校验会验证所有属性并返回一个错误消息集合,而快速失败模式通常按顺序验证到第一个字段不符合验证要求时,就可以直接拒绝请求了。
Hibernate Validator有以下两种验证模式:

普通模式(默认)
 会校验完所有的属性,然后返回所有的验证失败信息
快速失败返回模式
 只要有一个验证失败,则返回此条验证失败信息
两种验证模式配置方式:

@Configuration
public class ValidatorConfiguration {
    @Bean
    public Validator validator(){
        ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
                .configure() // true-快速失败返回模式    false-普通模式   
                .addProperty( "hibernate.validator.fail_fast", "true" )
                .buildValidatorFactory();
        Validator validator = validatorFactory.getValidator();

        return validator;
    }
}

四、分组校验

有这样一种场景,新增用户信息的时候,不需要验证userId(因为系统生成);
修改的时候则需要验证userId,这时候可用分组验证功能。

public interface GroupA {
}

public interface GroupB {
}
public class Person {

    @NotBlank
    @Range(min = 1,max = Integer.MAX_VALUE,message = "必须大于0",groups = {GroupA.class})
    private Integer userId;// 用户id

    @NotBlank
    @Length(min = 4,max = 20,message = "必须在[4,20]",groups = {GroupB.class})
    private String userName;// 用户名

    @NotBlank
    @Range(min = 0,max = 100,message = "年龄必须在[0,100]",groups={Default.class})
    private Integer age;// 年龄

    @NotNull(message = "地址不能为空",groups = {GroupB.class})
    private String address;// 地址
}

如上Person所示,3个分组分别验证字段如下:
GroupA验证字段userId;
GroupB验证字段userName,address;
Default验证字段age(默认分组)

A情景
只验证GroupA或GroupB标记的分组:
(可叠加 GroupA,GroupB)

    // 添加用户
    @PostMapping("/createuser2")  // 多个@Valid对应则多个BindingReslt
    public String createuser2(@Validated(GroupA.class) User user, BindingResult bindingResult){    
    if (bindingResult.hasErrors()){        
        return bindingResult.getFieldError().getDefaultMessage();
    }else{
        userService.createUser(userInfo.getTel(),userInfo.getPassWord());   
        return "OK";   
    }
}

B情景
指定验证组的顺序:
除了按组指定是否验证之外,还可以指定组的验证顺序,前面组验证不通过的,后面组不进行验证:
(GroupA>GroupB>Default)

@GroupSequence({GroupA.class, GroupB.class, Default.class})
public interface GroupOrder {
}

五、常见的注解

JSR303中内置的注解

注解名	作用
@Null	元素必须为 null
@NotNull	元素必须不为 null
@AssertTrue	元素必须为 true
@AssertFalse	的元素必须为 false
@Min(value)	元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)	元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value)	元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value)	元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=)	元素的大小必须在指定的范围内
@Digits (integer, fraction)	元素必须是一个数字,其值必须在可接受的范围内
@Past	元素必须是一个过去的日期
@Future	元素必须是一个将来的日期
@Pattern(regex=,flag=)	元素必须符合指定的正则表达式
Hibernate Validator对JSR303的扩展注解

注解名	作用
@NotBlank(message =)	字符串非null,且长度必须大于0
@Email	元素必须是电子邮箱地址
@Length(min=,max=)	字符串的大小必须在指定的范围内
@NotEmpty	字符串非空
@Range(min=,max=,message=)	元素必须在合适的范围内
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值