0
点赞
收藏
分享

微信扫一扫

通过 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());
}
}

 

参考链接

  • ​​@Valid和@Validated的总结区分​​


举报

相关推荐

0 条评论