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
相关产品推荐
相关产品推荐

