0
点赞
收藏
分享

微信扫一扫

参数校验(Hibernate-Validation)

新鲜小饼干 2022-03-31 阅读 41
spring

ibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。

依赖

        <!--参数校验-->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.14.Final</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.el</artifactId>
            <version>3.0.1-b11</version>
        </dependency>

Bean 注解

使用在字段上

@Null 限制只能为null

@NotNull 限制必须不为null

@NotEmpty 验证注解的元素值不为null且不为空,支持字符串、集合、Map和数组类型

@Max 限制必须为一个不大于指定值的数字

@Min 限制必须为一个不小于指定值的数字

@Range 限制必须在合适的范围内

@Size 限制字符长度必须在min到max之间

@AssertFalse 限制必须为false

@AssertTrue 限制必须为true

@DecimalMax 限制必须为一个不大于指定值的数字

@DecimalMin 限制必须为一个不小于指定值的数字

@Digits 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction

@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 @Future 限制必须是一个将来的日期

@NotBlank 验证注解的元素值不为null且去除空格后长度不为0,

@NotBlank只用于字符串

@Past 限制必须是一个过去的日期

@Pattern 限制必须符合指定的正则表达式

实例

/**
 *  省份和时间段
 */
@Data
public  class RegionTimeParam {
​
    /**
     * 人员所属省份编码
     */  
    @Length(max = 200, message = "The length of description can not exceed 200")
    @NotEmpty(message = "description can not be null")
    @NotNull
    private String provinceCode;
​
    /**
     *  1.最近一周 2.最近一月 3.最近一季 4.最近一年
     */
    @NotNull
    private Integer timeType;
​
​
}
​
@RestController 方法中在需要校验的 bean 前面添加 
public class TestController {
​
    @PostMapping("/addUser")
    public void addUser(@Validated @RequestBody User user) throws Exception {
        System.out.println(user);
    }
}

自定义校验

用户可以实现自己的校验注解。

下面的例子实现一个自定义注解,要求参数不能与设置的值相等

@Documented
​​​​​​​@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = NotEqualValidator.class)
public @interface NotEqual {
    String message() default "不能与给定的值相等";
​
    Class<?>[] groups() default {};
​
    Class<? extends Payload>[] payload() default {};
​
    String value();
}

注解实现类

public class NotEqualValidator implements ConstraintValidator<NotEqual, String> {
​
    private String value;
​
    @Override
    public void initialize(NotEqual constraintAnnotation) {
        this.value = constraintAnnotation.value();
    }
​
    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        return !s.equals(value);
    }
}
@RestController
@Validated
public class TestController {
​
    @GetMapping(value = "/test")
    public void test(@NotEqual("1111") @RequestParam String url) throws Exception {
        System.out.println(url);
    }
}

自定义异常处理

当参数校验没有通过时,Hibernate Validator 会抛出异常。但是 SpringBoot 默认的异常返回结果可能并不是用户所希望的,就像上面的例子一样。我只想获取报错信息,不希望返回异常的页面。这个时候我们可以通过 @ControllerAdvice 来自定义异常处理,返回自己希望的结果。

下面是一个自定义异常的例子。

返回结果封装类:

public class ServiceResult {
​
    private Integer code;
    private String message;
    private Object result;
​
    public ServiceResult () {
    }
​
    public ServiceResult(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
​
    // get set 省略
}

全局异常处理类,主要用来处理参数校验没有通过时的异常信息​

@ControllerAdvice
@RestController
public class GlobalExceptionHandler {
​
    // 方法参数校验异常
    @ExceptionHandler(value = ConstraintViolationException.class)
    public ServiceResult constraintViolationException(Exception e) {
        if (e.getMessage() != null) {
            int index = e.getMessage().indexOf(":");
            return new ServiceResult(HttpStatus.BAD_REQUEST.value(), index != -1 ?
                    e.getMessage().substring(index + 1).trim() : e.getMessage());
        }
        return new ServiceResult(HttpStatus.BAD_REQUEST.value(), null);
    }
​
​
    // Bean 校验异常
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ServiceResult notValidExceptionHandler(MethodArgumentNotValidException e) throws Exception {
        ServiceResult ret = new ServiceResult();
        ret.setCode(HttpStatus.BAD_REQUEST.value());
        if (e.getBindingResult() != null && !CollectionUtils.isEmpty(e.getBindingResult().getAllErrors())) {
            ret.setMessage(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
        } else {
            ret.setMessage(e.getMessage());
        }
        return ret;
    }
​
}
​

自定义返回结果:

{
  "code": 400,
  "message": "不能与给定的值相等",
  "result": null
}
​
举报

相关推荐

0 条评论