侧边栏壁纸
博主头像
此昵称不存在 博主等级

行动起来,活在当下

  • 累计撰写 35 篇文章
  • 累计创建 7 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

JSR303学习

Administrator
2024-03-24 / 0 评论 / 0 点赞 / 168 阅读 / 0 字 / 正在检测是否收录...

JSR303学习

springboot版本2.6.13

踩坑点

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

image.png

统一异常处理

示例代码

@RestControllerAdvice
2. (basePackages = "com.example.gulimall.product.controller")
@Slf4j
public class GulimallExceptionControllerAdvice {

![image.png](http://qn.3344love.cn/image.png)
    @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分组校验功能

  1. 需要在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的注解,里面的值填写对应对应的标记接口

自定义校验器

  1. 可增加一个自定义注解,注解内容可直接参考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的校验。

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区