自定义注解实现JSON字符串校验

分享自定义注解实现JSON字符串校验的过程及遇到的问题。

本文基于Java Bean Validation 的核心接口 ConstraintValidator(ConstraintValidator 的实现类可用于检验 Bean Validation 注解所标记的字段是否符合指定的规则)和@Constraint注解(指定的验证器类必须实现ConstraintValidator接口)

1、自定义注解

import tools.utils.JsonStringValidator;


import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;


@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = JsonStringValidator.class)
@Documented
public @interface CheckJsonString {
    /**
     * 返回消息
     *
     */
    String message() default "Value is not a valid JSON string";

    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

2、自定义JsonStringValidator类实现ConstraintValidator接口,并指定了泛型参数,重写该接口的isValid方法,实现字段是否为JSON字符串的校验。这个类实现了ConstraintValidator接口,所以它默认被spring管理成bean。

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hxsoft.product.common.tools.annotation.CheckJsonString;


public class JsonStringValidator implements ConstraintValidator<CheckJsonString, String> {
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void initialize(CheckJsonString jsonString) {
        // 初始化工作(如果有的话)
    }


    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 空值
        if (value == null || value.isEmpty()) {
            return true; // 空值不做处理
        }
        try {
            JsonNode tree = objectMapper.readTree(value);
            return true; // 是有效的JSON字符串
        } catch (Exception e) {
            return false; // 不是有效的JSON字符串
        }
    }
}

3、定义类并使用注解。

@Data
@EqualsAndHashCode(callSuper = false)
public class TestDto {

    private static final long serialVersionUID = -80645914200242954L;
   
    /**
     *表达式
     */
    @CheckJsonString
    private String expression;
    
    private String showName;
   
}

4、测试

@RestController
@RequestMapping("test")
public class TestController {
   
    @Resource
    private TestService service;

    @PostMapping("add") 
    public Result add(TestDto dto) {
        return service.add(dto);
    }

}

结果发现注解并未生效,后来查资料发现需要在实体类上使用 @Valid 或 @Validated 注解来触发校验。代码修改后生效

@RestController
@RequestMapping("test")
public class TestController {
   
    @Resource
    private TestService service;

    @PostMapping("add")
    @ApiOperation("新增")
    public Result add(@Valid TestDto dto) {
        return service.add(dto);
    }

}

知识点补充:

1、@Constraint注解是Java Bean Validation框架中的一个注解,用于自定义约束注解,即自定义校验规则。使用该注解时需要指定实现了ConstraintValidator接口的验证器类,用于验证该注解所标记的字段或参数是否符合自定义的校验规则。

@Constraint注解有以下属性:

validatedBy:用于指定实现了ConstraintValidator接口的验证器类。该属性的值是一个Class对象数组,可以指定多个验证器类。

message:用于指定当校验失败时,所返回的错误信息。可以使用占位符{},在校验器中使用具体的参数替换。

groups:用于指定分组,即根据不同的分组应用不同的校验规则。

payload:用于指定元数据,即可以通过该属性传递一些额外的验证信息。

2、ConstraintValidator 的实现类可用于检验 Bean Validation 注解所标记的字段是否符合指定的规则。该接口定义了两个泛型:A extends Annotation,T。其中 A 表示要校验的注解类型,T 表示注解所标记的字段的类型。

该接口有两个方法:
initialize(A constraintAnnotation) 方法:该方法用于初始化校验器,在校验之前调用,可以用来获取注解中定义的参数值。
isValid(T var1, ConstraintValidatorContext var2) 方法:该方法用于检验被注解标记的字段是否符合约束规则,返回一个 boolean 值表示校验结果。其中 var1 参数表示要校验的字段值,var2 参数是校验器的上下文环境,用于构建校验失败的提示信息。
ConstraintValidator 仅提供了校验方法的接口,要实现约束校验功能需要自己编写ConstraintValidator 的实现类,并结合具体的注解使用。



                        
参考链接:https://blog.csdn.net/weixin_42338901/article/details/130224185

解释ConstraintValidator<A extends Annotation, T>的含义 - 知乎

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值