springboot2.x使用validator 进行参数校验

1.简介

经常需要提供接口与用户交互(获取数据、上传数据等),由于这个过程需要用户进行相关的操作,为了避免出现一些错误的数据等,一般需要对数据进行校验,随着接口的增多,校验逻辑的冗余度也越来越大,虽然可以通过抽象出校验的方法来处理,但还是需要每次手动调用校验逻辑,相对来说还是不方便。 为了解决这个问题。 Java中提供了Bean Validation的标准,该标准规定了校验的具体内容,通过简单的注解就能完成必要的校验逻辑了,相对来说就方便了很多,而该规范其实只是规范,并没有具体的实现,Hibernate提供了具体的实现,也即Hibernate Validator,这个也是目前使用得比较多的验证器了。 。

springboot 中使用依赖

		
			org.springframework.boot
			spring-boot-starter-validation
		

2.参数多的时候直接绑定实体参数

public class BaseEntity {

    @Min(value = 1,message = "必须大于0")
    private Integer pageSize=1;

    @Range(min = 1,max = 1000,message = "一次性获取最大列表数不能超过1000")
    private Integer pageNum=10;

    @Transient
    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    @Transient
    public Integer getPageNum() {
        return pageNum;
    }

    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }
}

在接口中使用@Valid 和或者@Validated 注解校验,也可以在参数中直接绑定BindingResult 直接在代码中校验并返回错误信息,并且默认是校验全部再返回若是不想可以设置

@Configuration
public class ValidateConfig {

    @Bean
    public Validator validator(){
        ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
                .configure()
                //开启快速校验--默认校验所有参数,false校验全部
                .addProperty( "hibernate.validator.fail_fast", "true" )
                .buildValidatorFactory();
        Validator validator = validatorFactory.getValidator();

        return validator;
    }
}
    @RequestMapping(value = "articleList")
    @ResponseBody
    public ResultBean> articleList(@Valid Article article){
        PageInfo
articleAll1 = null; ResultBean> rlt = null; //校验错误,这样不雅观 // if(bindingResult.hasErrors()){ // rlt = new ResultBean<>(BlogContant.FAIL,BlogContant.CODE_9999, bindingResult.getAllErrors().get(0).toString(),articleAll1); // return rlt; // } try { articleAll1 = articleServiceImpl.getArticleList(article); rlt = new ResultBean<>(BlogContant.SUCCESS,BlogContant.CODE_0000,"获取文章列表成功",articleAll1); } catch (Exception e) { rlt = new ResultBean<>(BlogContant.FAIL,BlogContant.CODE_9999,e.getMessage(),articleAll1); log.error("查询文章列表异常!",e); } return rlt; }

3.直接绑定参数

当参数不是直接绑定实体的时候,此时直接在注解直接加在参数上,此时还必须在此controller 类上加上@Validated 注解。
    @RequestMapping(value = "articleList1")
    @ResponseBody
    public ResultBean> articleList1(@Range(min = 1,max = 1000,message = "一次性获取最大列表数不能超过1000") String pageNum){
        Article article = new Article();
        article.setPageNum(Integer.parseInt(pageNum));
        PageInfo
articleAll1 = null; ResultBean> rlt = null; //校验错误,这样不雅观 // if(bindingResult.hasErrors()){ // rlt = new ResultBean<>(BlogContant.FAIL,BlogContant.CODE_9999, bindingResult.getAllErrors().get(0).toString(),articleAll1); // return rlt; // } try { articleAll1 = articleServiceImpl.getArticleList(article); rlt = new ResultBean<>(BlogContant.SUCCESS,BlogContant.CODE_0000,"获取文章列表成功",articleAll1); } catch (Exception e) { rlt = new ResultBean<>(BlogContant.FAIL,BlogContant.CODE_9999,e.getMessage(),articleAll1); log.error("查询文章列表异常!",e); } return rlt; }

4.统一的异常返回

注意,当是实体绑定参数捕获异常为BindException,单个参数异常为:ConstraintViolationException
    /**
     * 一般的参数绑定时候抛出的异常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public ResultBean handleBindException(BindException ex){
        log.error(   "参数校验异常",ex);
        List defaultMsg = ex.getBindingResult().getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.toList());
        return new ResultBean(BlogContant.FAIL,BlogContant.CODE_9999,defaultMsg.get(0),null);
    }

    /**
     * 单个参数校验
     * @param ex
     * @return
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    @ResponseBody
    public ResultBean handleBindGetException(ConstraintViolationException ex){
        log.error(   "单个参数校验异常",ex);
        List defaultMsg = ex.getConstraintViolations()
                .stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.toList());
        return new ResultBean(BlogContant.FAIL,BlogContant.CODE_9999,defaultMsg.get(0),null);
    }

    /**
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ResultBean handleException(Exception ex){
        if(ex instanceof BlogRuntimeException){
            log.error( "抛出自定义异常",ex);
        }else {
            log.error( "系统内部异常",ex);
        }
        return new ResultBean(BlogContant.FAIL,BlogContant.CODE_9999,ex.getMessage(),null);
    }

4.使用外部异常信息

默认的外部异常信息配置名
必须使ASCII码否则乱码
使用:


    @Min(value = 1,message = "{blog.pageSize}")
    private Integer pageSize=1;

5.对象级联校验

常用验证注解

常用的注解主要有以下几个,作用及内容如下所示

@Null,标注的属性值必须为空

@NotNull,标注的属性值不能为空

@AssertTrue,标注的属性值必须为true

@AssertFalse,标注的属性值必须为false

@Min,标注的属性值不能小于min中指定的值

@Max,标注的属性值不能大于max中指定的值

@DecimalMin,小数值,同上

@DecimalMax,小数值,同上

@Negative,负数

@NegativeOrZero,0或者负数

@Positive,整数

@PositiveOrZero,0或者整数

@Size,指定字符串长度,注意是长度,有两个值,min以及max,用于指定最小以及最大长度

@Digits,内容必须是数字

@Past,时间必须是过去的时间

@PastOrPresent,过去或者现在的时间

@Future,将来的时间

@FutureOrPresent,将来或者现在的时间

@Pattern,用于指定一个正则表达式

@NotEmpty,字符串内容非空

@NotBlank,字符串内容非空且长度大于0

@Email,邮箱

@Range,用于指定数字,注意是数字的范围,有两个值,min以及max

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

你可能感兴趣的:(springboot)