You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

com.networknt JSON Schema Validator数字位数验证:是否需自定义验证器?

使用com.networknt JSON Schema Validator验证BigDecimal的位数限制

针对你的需求(整数部分最多5位、小数部分不超过3位,字段类型为BigDecimal),需要编写自定义验证器来实现整数部分的位数限制,小数部分可以通过multiplyOf关键字直接处理。以下是具体实现步骤:

1. 小数部分验证(无需自定义)

利用multiplyOf关键字限制小数位数不超过3位:

{
  "type": "number",
  "multiplyOf": 0.001
}

这个规则会确保数字是0.001的整数倍,即小数部分最多保留3位。

2. 整数部分自定义验证器实现

步骤1:创建自定义验证器类

继承AbstractJsonSchemaValidator,实现对整数部分位数的校验逻辑:

import com.networknt.schema.AbstractJsonSchemaValidator;
import com.networknt.schema.JsonSchema;
import com.networknt.schema.ValidationMessage;
import java.math.BigDecimal;
import java.util.Set;

public class IntegerMaxDigitsValidator extends AbstractJsonSchemaValidator {
    private final int maxDigits;

    public IntegerMaxDigitsValidator(int maxDigits) {
        this.maxDigits = maxDigits;
    }

    @Override
    public Set<ValidationMessage> validate(Object value, JsonSchema schema, String path, String fullPath) {
        if (!(value instanceof BigDecimal)) {
            return Set.of(); // 非BigDecimal类型不处理,由其他关键字校验
        }

        BigDecimal number = (BigDecimal) value;
        // 获取整数部分的字符串表示
        String integerPart = number.toPlainString().split("\\.")[0];
        // 处理负数的负号,不计入位数
        if (integerPart.startsWith("-")) {
            integerPart = integerPart.substring(1);
        }

        if (integerPart.length() > maxDigits) {
            return Set.of(ValidationMessage.builder()
                    .message("整数部分最多允许" + maxDigits + "位,当前为" + integerPart.length() + "位")
                    .path(path)
                    .build());
        }
        return Set.of();
    }
}

步骤2:注册自定义验证器

在初始化Schema Validator时,注册自定义关键字和对应的验证器:

import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SchemaValidatorsConfig;
import com.networknt.schema.ValidationMessage;
import java.util.Set;

public class SchemaValidatorSetup {
    public static JsonSchemaFactory createCustomSchemaFactory() {
        SchemaValidatorsConfig config = new SchemaValidatorsConfig();
        // 注册自定义关键字"integerMaxDigits"
        config.addValidator("integerMaxDigits", (schemaNode, jsonSchema, config1) -> {
            int maxDigits = schemaNode.asInt();
            return new IntegerMaxDigitsValidator(maxDigits);
        });

        return JsonSchemaFactory.getInstance(config);
    }

    public static void main(String[] args) {
        // 示例JSON Schema
        String schemaJson = """
                {
                  "type": "number",
                  "multiplyOf": 0.001,
                  "integerMaxDigits": 5
                }
                """;

        JsonSchemaFactory factory = createCustomSchemaFactory();
        JsonSchema schema = factory.getSchema(schemaJson);

        // 测试用例
        BigDecimal validNum = new BigDecimal("12345.123");
        Set<ValidationMessage> validErrors = schema.validate(validNum);
        System.out.println("有效数字校验结果:" + validErrors); // 输出空集合

        BigDecimal invalidIntegerNum = new BigDecimal("123456.12");
        Set<ValidationMessage> invalidIntegerErrors = schema.validate(invalidIntegerNum);
        System.out.println("整数部分超限校验结果:" + invalidIntegerErrors); // 输出错误信息

        BigDecimal invalidDecimalNum = new BigDecimal("1234.1234");
        Set<ValidationMessage> invalidDecimalErrors = schema.validate(invalidDecimalNum);
        System.out.println("小数部分超限校验结果:" + invalidDecimalErrors); // 输出错误信息
    }
}

步骤3:在JSON Schema中使用自定义关键字

将自定义关键字integerMaxDigits添加到你的Schema中,结合multiplyOf即可完成完整校验:

{
  "type": "number",
  "multiplyOf": 0.001,
  "integerMaxDigits": 5
}

注意事项

  • 处理负数时,负号不计入整数部分的位数,上述代码已经包含该逻辑。
  • 如果你的DTO字段在序列化/反序列化时会被转为BigDecimal,确保验证时传入的是BigDecimal类型(避免字符串转数字时的精度丢失)。

内容的提问来源于stack exchange,提问作者Janek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:17:10