SpringBoot+HibernateValidator优雅的接口入参校验(代码实例)

SpringBoot+HibernateValidator优雅的接口入参校验(代码实例)

  • HIbernateValidator有效注解详解
  • HIbernateValidator注释的接口入参类实例
  • 接口实例
  • 测试结果
  • 捕获validator抛出的异常,友好展现异常信息

HIbernateValidator有效注解详解

 * @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(regex=,flag=) 被注释的元素必须符合指定的正则表达式
 * Hibernate Validator 附加的 constraint
 * @NotBlank(message =)   验证字符串非null,且长度必须大于0
 * @Email 被注释的元素必须是电子邮箱地址
 * @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
 * @NotEmpty 被注释的字符串的必须非空
 * @Range(min=,max=,message=) 被注释的元素必须在合适的范围内
 * @Digits(integer=, fraction=) 限定被注释参数的整数位数和小数位数

HIbernateValidator注释的接口入参类实例

@Data
public class UserRequest {
    @NotBlank(message = "interfaceId不能为空")
    private String interfaceId;
    @NotEmpty(message = "uuid不能为空")
    private String uuid;
    @Length(min = 10, message = "sign长度必须大于10")
    private String sign;
    @Valid // 如果不为空,则校验子类数据
    private User data;
    @NotBlank
    @Pattern(regexp = "^[0-9]{4}-[0-9]{2}-[0-9]{2}$]", message = "requestDate时间格式为yyyy-MM-dd")
    private String requestDate;
    @Max(value = 100, message = "amount的最大值为100")
    private Integer amount;
    @Digits(integer = 9, fraction=2, message = "price格式不正确")
    private BigDecimal price;
    }

接口实例

若要使用hibernate validator校验接口入参,在接口的参数上必须加上@Validated注解,否则入参实体内的validator注解不生效。

    @PostMapping("/set-value")
    public String setValue(@Validated @RequestBody UserRequest request){
        logger.info("接收set-value请求[{}]", request);
        return "success";
    }

测试结果

使用postman测试

SpringBoot+HibernateValidator优雅的接口入参校验(代码实例)_第1张图片
结果接收到一堆异常堆栈:
org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public java.lang.String com.term.spring_batch.controller.HelloController.setValue(com.term.spring_batch.model.dto.UserRequest) with 2 errors: [Field error in object ‘userRequest’ on field ‘requestDate’: rejected value [null]; codes [NotBlank.userRequest.requestDate,NotBlank.requestDate,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userRequest.requestDate,requestDate]; arguments []; default message [requestDate]]; default message [不能为空]] [Field error in object ‘userRequest’ on field ‘uuid’: rejected value [null]; codes [NotEmpty.userRequest.uuid,NotEmpty.uuid,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userRequest.uuid,uuid]; arguments []; default message [uuid]]; default message [uuid不能为空]] ……

捕获validator抛出的异常,友好展现异常信息

仔细看确实是我们的注解生效了,并给出了一些我们自定义的提示。但是异常堆栈这种报错太不友好了,我们使用Spring的统一异常处理机制(全局异常处理类的写法请参考)捕获一下 MethodArgumentNotValidException异常
代码如下:

    // 方法参数校验异常
    @ExceptionHandler(value = ConstraintViolationException.class)
    public String constraintViolationException(ConstraintViolationException e) {
        if (e.getMessage() != null) {
            int index = e.getMessage().indexOf(":");
            String msg = index != -1 ? e.getMessage().substring(index + 1).trim() : e.getMessage();
            logger.info(msg);
            return msg;
        }
        return null;
    }

    // Bean 校验异常
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public String notValidExceptionHandler(MethodArgumentNotValidException e) throws Exception {
        String msg = null;
        if (e.getBindingResult() != null && !CollectionUtils.isEmpty(e.getBindingResult().getAllErrors())) {
            msg = e.getBindingResult().getFieldErrors().stream()
                    .map(FieldError::getDefaultMessage).collect(Collectors.joining(","));
            logger.info(msg);
        } else {
            logger.info(msg = e.getMessage());
        }
        return msg;
    }

再次测试,结果为:

uuid不能为空,requestDate不能为空

你可能感兴趣的:(Java菜鸡笔记,java,spring,java,SpringBoot)