通过 validation 注释进行字段校验验证

注解说明

  • @Null 被注释的元素必须为null
  • @NotNull 被注释的元素不能为null
  • @AssertTrue 被注释的元素必须为true
  • @AssertFalse 被注释的元素必须为false
  • @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @Size(max,min) 被注释的元素的大小必须在指定的范围内(用于校验集合个数)。
  • @Digits(integer,fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内,integer整数的位数,fraction小数位的进度,fraction=2就是保留两位小数
  • @Past 被注释的元素必须是一个过去的日期
  • @PastOrPresent 被注释的元素必须是一个过去或者现在的日期
  • @Future 被注释的元素必须是一个将来的日期
  • @FutureOrPresent 被注释的元素必须是一个将来或者现在的日期
  • @Pattern(value) 被注释的元素必须符合指定的正则表达式。
  • @Email 被注释的元素必须是电子邮件地址
  • @Length 被注释的字符串的大小必须在指定的范围内
  • @NotEmpty 被注释的字符串必须非空
  • @Range 被注释的元素必须在合适的范围内
  • @NotBlank 字符串,不为空字符串
  • @Positive 数字,正数
  • @PositiveOrZero 数字,正数或0
  • @Negative 数字,负数
  • @NegativeOrZero 数字,负数或0

 

实体对象

@Data
public class VerifyRuleDTO {

    private Long id;

    @NotBlank(message = "can not be empty")
    private String flowId;
    
    @NotBlank(message = "can not be empty")
    private String ruleCode;

    @NotBlank(message = "can not be empty")
    private String ruleName;

    @Max(10)
    @Min(5)
    private int amt;

//	@Pattern(regexp = "desc|asc", message = "排序值无效")
//    private String sortOrder = "asc";
}

 

控制层

@RestController
@RequestMapping("/api/verify/rule/v1")
@Slf4j
public class VerifyRuleController {
	@RequestMapping(value = "saveRule", method = RequestMethod.POST)
    public AiResponse saveRule(@Valid @RequestBody VerifyRuleDTO verifyRule) {
		// ...
		return AiResponse.success("insert successful.");
	}
}

 

全局异常控制

@ControllerAdvice
@Slf4j
public class ExceptionHandler {
	
	@ExceptionHandler(Exception.class)
    @ResponseBody
    public AiResponse exceptionHandler(Exception ex) {
        log.error("exception message[{}]", ex.getMessage());

        if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException) ex;
            FieldError fieldError = methodArgumentNotValidException.getBindingResult().getFieldError();
            if (fieldError != null) {
            	// 校验失败的字段名
                String fieldName = fieldError.getField();
                // 字段校验失败的具体信息
                String message = fieldError.getDefaultMessage();
                return AiResponse.failed(String.format("%s %s", fieldName, message));
            }

            return AiResponse.failed(ex.getMessage());
        }

        return AiResponse.failed(ex.getMessage());
    }
    
}

 

测试结果

请求体

{
	"flowId": "answer",
	"ruleCode": "1",
	"ruleName": "2",
	"amt": 1
}

 

响应体

{
    "code": "0001",
    "desc": "failed",
    "data": "amt 最小不能小于5"
}

 

全局异常控制

@ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public Response handleMethodArgumentNotValidException(HttpServletRequest request, MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getFieldErrors().stream().map(ele -> ele.getField() + ele.getDefaultMessage()).collect(Collectors.joining(","));
        return Response.failed(ResponseCodeEnum.INVALID_ARGUMENT, message);
    }

 

hibernate的校验模式配置

如果请求存在多个参数都校验失败,则遇到第一个校验失败就抛出异常,接下来的异常参数不做校验

@Configuration
public class ValidatorConfig {

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor(@Qualifier("validator") Validator validator) {
        MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        // 设置 validator 为快速失败返回
        methodValidationPostProcessor.setValidator(validator);
        return methodValidationPostProcessor;
    }

    @Bean
    public Validator validator() {
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
                .configure()
                // failFast=true: 只要出现校验失败的情况就立即结束校验,不再进行后续的校验
                .failFast(true)
                .buildValidatorFactory();

        return validatorFactory.getValidator();
    }

}

Hibernate Validator 6.1.5.Final - Jakarta Bean Validation Reference Implementation: Reference Guide

 

@Digits使用

class Item {
   @Digits(integer = 6, fraction = 2, message = "{javax.validation.constraints.Digits.message}")
   private BigDecimal amount;
}

在上面的类中integer并且fraction是强制性的,并且消息是可选参数,@Digit并且我们可以配置自定义错误消息。

现在,我们在源目录中创建一个名为ValidationMessages.properties的属性文件。

javax.validation.constraints.Digits.message = "custom error message will be here"
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

springboot在2.3之后,spring-boot-starter-web的依赖项已经去除了validate依赖

@Data
public class Request<T> {
    private String requestId;
    private String visitKey;
    // SpringBoot针对泛型失效的解决方案
    @Valid
    private T body;
}
@Slf4j
@ControllerAdvice
@ResponseBody
public class GlobalController {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Response handleBindException(MethodArgumentNotValidException e) {
        return Response.failed(ResponseEnum.REQUEST_PARAM_ERROR, e.getBindingResult().getFieldError().getDefaultMessage());
    }
}

 

参考链接

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jaemon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值