SpringBoot & Hibernate Validator 整合

SpringBoot整合Hibernate validator校验框架

在这里插入图片描述
作用:

  • 将验证逻辑与业务逻辑之间进行了分离,降低了程序耦合度

1.引入jar包

  <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.1.0.Final</version>
            <scope>compile</scope>
 </dependency>

2.配置校验配置类

/**
 * @program: hibrenate_validator_demo
 * @description: ValidatorConfiguration
 * @author: Z_R
 * @create: 2020-11-22 20:53
 */
@Configuration
public class ValidatorConfiguration {
//    @Bean
//    public MethodValidationPostProcessor methodValidationPostProcessor() {
    // 如下直接配置bean 会校验所有 参数,返回所有错误提示
//        return new MethodValidationPostProcessor();
//    }

    // spring 对 validator 的封装,如果当前bean不做配置,那么 spring的 @Validated 作用下的 快速失败 不会生效
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
        /**设置validator模式为快速失败返回*/
        postProcessor.setValidator(this.validator());
        return postProcessor;
    }

    // 配置 Validator 快速失效
    @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;
    }
}

在这里插入图片描述3.添加POJO对象添加约束注解

/**
 * @program: hibrenate_validator_demo
 * @description:
 * @author: Z_R
 * @create: 2020-11-22 20:01
 */
@Data
@AllArgsConstructor
public class TestRequestVO implements Serializable {
    @NotNull(message = "id不能为空")
    private Integer id;

    /**
     * ""  加强版 的  NotNull  "" 也可以捕获
     */
    @NotBlank(message = "name不能为空")
    private String name;

    @Max(150)
    @Min(0)
    private Integer age;


    /**
     * @AssertTrue(message="必须为true")
     */
    @AssertFalse(message = "必须为false")
    private Boolean flag;

    /**
     * regexp  正则表达式
     */
    @Pattern(regexp = "^[0-9]{4}-[0-9]{2}-[0-9]{2}$", message = "出生日期格式不正确")
    private String birthday;

    @NotNull(message = "list不能为空")
    List<TestRequestVO> list;

    /**
     * 层级校验,校验对象内部属性  --- 引用类型 -- 对象级联校验
     */
    @Valid
    @NotNull(message = "testRequestDTO不能为空")
    private TestRequestVO testRequestDTO;
}

在这里插入图片描述

在这里插入图片描述

4.添加结果处理类

/**
 * @program: hibrenate_validator_demo
 * @description: ResultEntity
 * @author: Z_R
 * @create: 2020-11-22 20:16
 */
@Data
@AllArgsConstructor
public class ResultEntity {
    private int code;
    private Object data;
    private String msg;
    private boolean success;

    public ResultEntity() {
    }

    public ResultEntity(int status) {
        this.code = status;
    }

    public ResultEntity(int status, Object data) {
        this.code = status;
        this.data = data;
    }

    public ResultEntity(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    public ResultEntity setMsg(String msg) {
        this.msg = msg;
        return this;
    }


}

5.配置全局异常处理

/**
 * @program: hibrenate_validator_demo
 * @description: TestExceptionHandler
 * @author: Z_R
 * @create: 2020-11-22 20:23
 */
@SuppressWarnings("ALL")
@ControllerAdvice
public class TestExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(TestExceptionHandler.class);

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResultEntity handleException(Exception e) {

        //MissingServletRequestParameterException
        if (e instanceof MissingServletRequestParameterException) {
            // @RequestParam 要求传入的参数 未传
            log.error("MissingServletRequestParameterException ==== " + e.getMessage(), e);
            MissingServletRequestParameterException mise = (MissingServletRequestParameterException) e;
            return new ResultEntity(HttpStatus.BAD_REQUEST.value(), null).setMsg("参数" + mise.getParameterName() + "不能为空");
        }

        if (e instanceof MethodArgumentTypeMismatchException) {
            // @RequestParam 传入参数类型不匹配
            log.error("MethodArgumentTypeMismatchException ==== " + e.getMessage(), e);
            return new ResultEntity(HttpStatus.BAD_REQUEST.value(), null).setMsg("参数类型不匹配");
        }

        log.error(e.getMessage(), e);

        BindingResult result = null;
        if (e instanceof MethodArgumentNotValidException) {
            result = ((MethodArgumentNotValidException) e).getBindingResult();
        } else if (e instanceof BindException) {
            result = ((BindException) e).getBindingResult();
        } else if (e instanceof ConstraintViolationException) {
            // 使用@Valid 校验对象 参数不满足条件时 会抛出的 异常 对应的处理逻辑
            Set<ConstraintViolation<?>> constraintViolations = ((ConstraintViolationException) e).getConstraintViolations();
            List<String> errors = new ArrayList<>();
            for (ConstraintViolation<?> violation : constraintViolations) {
                errors.add(violation.getMessage());
            }
            return new ResultEntity(HttpStatus.OK.value(), errors);
        }

        if (result != null) {
            List<String> errors = new ArrayList<>();
            for (ObjectError error : result.getAllErrors()) {
                errors.add(error.getDefaultMessage());
            }
            return new ResultEntity(HttpStatus.BAD_REQUEST.value(), errors);
        }

        return new ResultEntity(HttpStatus.BAD_REQUEST.value());
    }

}

6.在Controller层配置需要校验参数

/**
 * @program: hibrenate_validator_demo
 * @description:
 * @author: Z_R
 * @create: 2020-11-22 19:48
 */
@RestController
@Validated
public class TestController {
    private static Logger logger = LoggerFactory.getLogger(TestController.class);


    @GetMapping("/test1")
    public String test1(@Valid TestRequestVO testRequestVO) {
        logger.info(testRequestVO.toString());
        //return new ResultEntity();
        return  "test1";
    }


    @PostMapping("/test2")
    public ResultEntity test2(@RequestBody @Valid TestRequestVO testRequestVO) {
        logger.info(testRequestVO.toString());
        return new ResultEntity();
    }

    /**
     * @param id
     * @param name
     * @param age
     * @return
     * @RequestParam 默认required属性为true,代表当前参数不能不传,所以已经具备 @NotNull的能力
     * 需要在 类前面加
     * //@Validated  用于 @RequestParam 类型 接口 参数 的 validator 校验,
     * // 只有在类上加了这个注解,test3 @Min 等validator注解才能生效
     */
    @GetMapping("/test3")
    public String test3(@RequestParam(value = "id") Integer id,
                        @RequestParam(value = "name", required = false) String name,
                        @Min(value = 10, message = "age最小只能是10") @RequestParam(value = "age", required = false) Integer age) {
        return "test3";
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
常用注解:

@Valid	                        被注释的元素是一个对象,需要检查此对象的所有字段值
@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(value)	                被注释的元素必须符合指定的正则表达式

总结:
通过使用Hibernate Validator校验框架,可以在设计之初规避很多错误

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值