JSR303学习
springboot版本2.6.13
踩坑点
- 增加了JSR303相关注解及@Valid 注解,但是不生效,解决方案,导入相关依赖才能生效
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- postman请求接口后不返回error相关信息,只有控制台会打印相关异常,需要在ymal配置文件中加入相关配置
server:
error: #303校验错误信息提示
include-binding-errors: always
include-message: always

统一异常处理
示例代码
@RestControllerAdvice
2. (basePackages = "com.example.gulimall.product.controller")
@Slf4j
public class GulimallExceptionControllerAdvice {

@ExceptionHandler(value = MethodArgumentNotValidException.class)
public R ExceptionHandler(MethodArgumentNotValidException exception){
log.error("数据校验出现问题{}, 异常类型{}", exception.getMessage(), exception.getClass());
BindingResult bindingResult = exception.getBindingResult();
Map<String, String> map = new HashMap<>();
for (FieldError fieldError : bindingResult.getFieldErrors()) {
map.put(fieldError.getField(), fieldError.getDefaultMessage());
}
return R.error(400, "数据校验异常").put("data", map);
}
}
JSR303分组校验功能
- 需要在JSR303的相关校验注解上增加groups,并指定一个标记接口,例如
/**
* 品牌id
*/
@NotNull(message = "修改必须指定id", groups = {UpdateGroup、.class})
@Null(message = "新增不能指定id", groups = {AddGroup.class})
@TableId
private Long brandId;
UpdateGroup和AddGroup分别代表着更新和操作时应该启动那个注解的校验,或者填写多个,多重校验UpdateGroup、AddGroup均为标记接口,并无实际实现及方法
2. 同时对应的controller需要增加注解@Validated({AddGroup.class}),该注解为sping的注解,里面的值填写对应对应的标记接口
自定义校验器
- 可增加一个自定义注解,注解内容可直接参考JSR303已有注解新增,如示例:
@Documented
@Constraint(
validatedBy = {ListValueConstraintValidator.class}
)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ListValue {
String message() default "{com.example.gulimall.common.valid.ListValue.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
int[] values() default {};
}
@Constraint可指定哪个校验器去校验增加该注解字段的具体代码逻辑,可填写多个校验器,校验启需要实现ConstraintValidator<A extends Annotation, T>接口,如示例:
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {
private Set<Integer> set = new HashSet<>();
// 初始化方法
@Override
public void initialize(ListValue constraintAnnotation) {
int[] values = constraintAnnotation.values();
for (int value : values) {
set.add(value);
}
}
// 判断是否校验成功
@Override
public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) {
return set.contains(integer);
}
}
其中A extends Annotation需要填写相应注解,T则填写实际校验字段的类型,之后重写initialize和isValid方法,其中initialize方法为初始化方法,可以拿校验注解的相关的注解信息,包括参数值等,isValid为实现校验逻辑的具体方法,第一个参数为被校验字段实际的值,根据返回的布尔类型来判断校验是否通过,注解中的message可以定义默认的错误提示信息,例如:com.example.gulimall.common.valid.ListValue.message=必须填写指定的值,需要在当前资源目录下创建名为ValidationMessages.properties的文件,并填写如上例中类型的内容即可实现,以上便可实现一个简单的自定义JSR303的校验。
评论区