SpringBoot(20) - 校验(1) - 使用Hibernate Validator

参考:https://docs.spring.io/spring-boot/docs/1.5.17.RELEASE/reference/htmlsingle/#boot-features-validation

 

1. Validation

只要实现了JSR-303规范的实例(例如Hibernate validator)在类路径上,Bean Validation 1.1支持的方法验证功能就会自动启用。这允许bean方法在其参数 和/或 返回值上使用javax.validation约束进行注释。 具有此类带注释方法的目标类需要在type级别使用@Validated注解进行注释,以便搜索其内联约束注释的方法。

以下示例触发方法第一个参数的校验,校验长度在8-10之间:

@Service
@Validated
public class MyBean {
    public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code, Author author {
        ...
    }
}

 

2. Hibernate Validator

SpringBoot中添加spring-boot-starter-web依赖即会自动引用依赖的Hibernate validator,所以无需再手动添加依赖。

我们一般在Controller层校验参数,校验分为两种:封装的Bean、方法参数简单验证。

2.1 校验Bean

(1)定义Bean

public class UserRegisterParam {

    @NotBlank(message = "用户名不能为空")
    private String name;

    @Range(min = 1, max = 200, message = "年龄范围应该在1-200内")
    private Integer age;

    @NotEmpty(message = "密码不能为空")
    @Length(min = 6, max = 8, message = "密码长度为6-8位")
    @Pattern(regexp = "[a-zA-Z]*", message = "密码只能是字母")
    private String password;
    get、set略
}

(2)Controller

使用@Valid注解标识需要验证的Bean,@Valid和BindingResult一一对应;如果有多个@Valid,那么每个@Valid后面跟着的BindingResult就是对应@Valid的验证结果。

@RestController
@RequestMapping("/user")
public class UserController {
    
    @PostMapping("/api/register")
    public String register(@Valid UserRegisterParam param, BindingResult result) throws Exception {
        StringBuilder sBuilder = new StringBuilder();
        if (result.hasErrors()) {
            List<ObjectError> list = result.getAllErrors();
            for (ObjectError error : list) {
                sBuilder.append(error.getDefaultMessage()).append("\n");
            }
        } else {
            sBuilder.append("success");
        }
        return  sBuilder.toString();
    }
}

 

2.2 校验方法参数

(1)添加MethodValidationPostProcessor的Bean

@Configuration
public class ValidatorConfig {
    // 配置方法参数校验
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }
}

(2)Controller

在Controller类上添加@Validated注解,在方法参数上直接添加校验规则注解,对于Bean校验,仍然使用@Valid注解。校验失败后,不管是参数校验、Bean校验,统一抛出ConstraintViolationException异常。

@Validated
@RestController
@RequestMapping("/user")
public class UserController {

    @PostMapping("/api/login")
    public String login(
        @Length(min = 6, message = "账号长度至少6位") @RequestParam String account,
        @Length(min = 6, max = 8, message = "密码长度6-8位") @RequestParam String password) throws Exception {
        return "login success";
    }
}

(3)统一异常处理

对校验抛出的异常ConstraintViolationException进行捕获

@ControllerAdvice
@Component
public class GlobalExceptionHandler {
    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public @ResponseBody String handle(ConstraintViolationException exception) {
        Set<ConstraintViolation<?>> violations = exception.getConstraintViolations();
        StringBuilder sBuilder = new StringBuilder();
        for (ConstraintViolation<?> violation : violations) {
            sBuilder.append(violation.getMessage() + "\n");
        }
        return sBuilder.toString();
    }
}

 

2.3 校验模式

Hibernate Validator有两种校验模式:

  • 普通模式(默认):交验完所有属性,返回验证失败的信息
  • 快速失败返回模式:只要有一个验证失败则立即返回

(1)配置

@Bean
public Validator validator() {
    ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
        .configure()
        .failFast(true)// true:快速失败返回模式 false:普通模式
        .buildValidatorFactory();
}

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

(2)方法参数校验中使用快速失败返回模式

对MethodValidationPostProcessor设置Validator(此时不是用的Validator校验,所以只配置Validator不起作用),修改ValidatorConfig如下:

@Configuration
public class ValidatorConfig {
    // 配置方法参数校验
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
        // 设置validator模式为快速失败返回
        postProcessor.setValidator(validator());
        return postProcessor;
    }

    // 配置hibernate Validator为快速失败返回模式
    @Bean
    public Validator validator() {
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
            .configure()
            .failFast(true)// true:快速失败返回模式 false:普通模式
            .buildValidatorFactory();
    }
}

 

参考:https://www.cnblogs.com/mr-yang-localhost/p/7812038.html

http://www.cnblogs.com/bianzy/p/6639799.html

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值