SpringBoot参数校验@Validated

介绍

@Validated与@Valid的区别

  1. @Validated注解是spring提供的,提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制。没有添加分组属性时,默认验证没有分组的验证属性(Default分组);
  2. @Validated:可以用在类型、方法和方法参数上,但是不能用在成员属性(字段上;
  3. @Validated: 用在方法入参上无法单独提供嵌套验证功能,也无法提示框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。
  4. @Valid:作为标准JSR-303规范,还没有吸收分组的功能
  5. @Valid:可以用在方法、方法参数、构造函数、方法参数和成员属性(字段)上;
  6. @Valid加在方法参数时并不能够自动进行嵌套验证,而是用在需要嵌套验证类的相应字段上,来配合方法参数上@Validated或@Valid来进行嵌套验证

注解说明

在这里插入图片描述

Hibernate Validator两种校验模式——普通&快速

  • 普通模式(会校验完所有的属性,然后返回所有的验证失败信息默认是这个模式)

  • 快速失败返回模式(只要有一个字段验证失败,就返回结果)

在@Configuration Class中配置以下代码,将Validator设置为快速失败返回模式

@Bean
    public Validator validator(){
        ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class)
                .configure()
                .addProperty( "hibernate.validator.fail_fast", "true" )
                .buildValidatorFactory();
        Validator validator = validatorFactory.getValidator();
        return validator;
    }

使用

引入依赖

由于spring-boot-starter-web(springboot 2.3以下版本)依赖默认集成了Hibernate Validator,所以无需添加任何依赖和相关配置,只需要在项目中引入spring-boot-starter-web依赖即可(演示springboot版本为2.5.4)

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
 </dependency>

全局异常处理器

@RestControllerAdvice
@Slfj
@AutoConfigurationPackage
public class GlobalExceptionHandler {
    //spring-context包里面的异常
    //实体对象前不加@RequestBody注解,单个对象内属性校验未通过抛出的异常类型
    @ExceptionHandler(BindingException.class)
    public ResponseEntity<ExceptionResponseVO> methodArguments(BindingException e){
        log.warn("throw BindingException,{}",e);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ExceptionResponseVO.error(NEError.INVALID_PARAMETER, e.getBindingResult().getFieldError().getDefaultMessage()));
    }

       //实体对象前不加@RequestBody注解,校验方法参数或方法返回值时,未校验通过时抛出的异常
    //Validation-api包里面的异常
    @ExceptionHandler(ValidationException.class)
    public ResponseEntity<ExceptionResponseVO> methodArguments(ValidationException e){
        log.warn("throw ValidationException,{}",e);
       return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ExceptionResponseVO.error(NEError.INVALID_PARAMETER,e.getCause().getMessage()));
    }

    //spring-context包里面的异常,实体对象前加@RequestBody注解,抛出的异常为该类异常
    //方法参数如果带有@RequestBody注解,那么spring mvc会使用RequestResponseBodyMethodProcessor      
    //对参数进行序列化,并对参数做校验
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ExceptionResponseVO> methodArguments(MethodArgumentNotValidException e){
        log.warn("throw MethodArgumentNotValidException,{}",e);
       return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ExceptionResponseVO.error(NEError.INVALID_PARAMETER,                e.getBindingResult().getFieldError().getDefaultMessage()));
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity methodArguments(Exception e){
        log.warn("throw exception,{}",e);
        return ResponseEntity.badRequest().body(e.getMessage());
    }
}

自定义参数检验

需求:我需要根据传入多个参数,有一部分参数校验条件取决于其他参数的输入,比如我只需要当name参数等于“testUser”时,校验age是否大于20,当name=“user”,校验age是否大于30,没有值则不校验

1.分组

根据校验逻辑分组

@Data
@NoArgsConstructor
@AllArgsConstructor
//指定组序列化提供器
@GroupSequenceProvider(value = AccountGroupSeqProvider.class)
public class AccountConfigParam {
  
    /**
     * 账号名称
     */
    @NotBlank(message = "账号名称不可为空")
    private String username;

    /**
     * 账号id
     */
    @NotBlank(message = "账号id不可为空", groups = {WeiBoGroup.class, WeiXinGroup.class})
    private String userid;

    
    public interface FirstGroup{}

    
    public interface SecondGroup {
    }


2. 自定义分组序列化提供器

public class AccountGroupSeqProvider implements DefaultGroupSequenceProvider<AccountConfigParam> {
    @Override
    public List<Class<?>> getValidationGroups(AccountConfigParam param) {

        List<Class<?>> defaultGroupSequency = new ArrayList<>();
        //这一步不能省略,否则会抛错
        defaultGroupSequency.add(AccountConfigParam.class);
        if (param!=null){
            if ("user".equals(param.getMedium())){
                defaultGroupSequency.add(AccountConfigParam.WeiBoGroup.class);
            }
        }
        return defaultGroupSequency;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值