当前位置: 首页 > 工具软件 > sm-validator > 使用案例 >

JSON Schema定义 +Networknt validator格式校验

姜淇
2023-12-01

一、介绍

JSON Schema是基于JSON的格式的规范,用于定义JSON数据的结构。

官网:https://ajv.js.org/json-schema.html

在线验证:https://www.jsonschemavalidator.net/

在json-schema官网上可以看到,java版本的validator库推荐了以下几种方案:

  • Snow 2019-09, draft-07, -06 Uses Maven for the project and Gson under the hood. (GNU Affero General Public License v3.0)

  • Justify draft-07, -06, -04 (Apache License 2.0)

常用的json-schema-validator库有:everit-org/json-schema和networknt/json-schema-validator ,在everit-org/json-schema的github介绍中可知,如果项目代码中使用jackson进行的json解析,推荐使用后者进行校验;如果使用的是org.json API 进行json解析,推荐使用前者校验。

everit:GitHub - everit-org/json-schema: JSON Schema validator for java, based on the org.json API

networknt: https://github.com/networknt/json-schema-validator

fge:https://github.com/java-json-tools/json-schema-validator

注意:fge/json-schema-validator也称作 java-json-tools/json-schema-validator

参考https://blog.csdn.net/liuxiao723846/article/details/108578544

二、性能对比

在networknt github上有一个三者的性能对比,最快的是networknt。

fge: 7130ms

everit-org: 1168ms

networknt: 223ms

三、json Schema示例

示例1

{
    "type":"object",
    "required":[
        "client_side_conn_param",
        "server_side_conn_param",
        "bypass_duplicated_packet"
    ],
    "properties":{
        "client_side_conn_param":{
            "$ref":"#/$defs/conn_params"
        },
        "server_side_conn_param":{
            "$ref":"#/$defs/conn_params"
        },
        "bypass_duplicated_packet":{
            "type":"integer",
            "enum":[
                0,
                1
            ]
        }
    },
    "$defs":{
        "conn_params":{
            "type":"object",
            "required":[
                "tcp_maxseg",
                "nodelay",
                "keep_alive",
                "ttl",
                "user_timeout"
            ],
            "properties":{
                "tcp_maxseg":{
                    "type":"object",
                    "properties":{
                        "enable":{
                            "type":"integer",
                            "enum":[
                                0,
                                1
                            ]
                        },
                        "maxseg":{
                            "type":"integer"
                        }
                    },
                    "if":{
                        "properties":{
                            "enable":{
                                "const":1
                            }
                        }
                    },
                    "then":{
                        "properties":{
                            "maxseg":{
                                "minimum":536,
                                "maximum":1460
                            }
                        },
                        "required":[
                            "maxseg"
                        ]
                    }
                },
                "nodelay":{
                    "type":"integer",
                    "enum":[
                        0,
                        1
                    ]
                },
                "keep_alive":{
                    "type":"object",
                    "required":[
                        "enable"
                    ],
                    "properties":{
                        "enable":{
                            "type":"integer",
                            "enum":[
                                0,
                                1
                            ]
                        },
                        "tcp_keepcnt":{
                            "type":"integer"
                        },
                        "tcp_keepidle":{
                            "type":"integer"
                        },
                        "tcp_keepintvl":{
                            "type":"integer"
                        }
                    },
                    "if":{
                        "properties":{
                            "enable":{
                                "const":1
                            }
                        }
                    },
                    "then":{
                        "properties":{
                            "tcp_keepcnt":{
                                "minimum":1,
                                "maximum":222
                            },
                            "tcp_keepidle":{
                                "minimum":30,
                                "maximum":7200
                            },
                            "tcp_keepintvl":{
                                "minimum":15,
                                "maximum":75
                            }
                        },
                        "required":[
                            "tcp_keepcnt",
                            "tcp_keepidle",
                            "tcp_keepintvl"
                        ]
                    }
                },
                "ttl":{
                    "type":"integer",
                    "minimum":1,
                    "maximum":255
                },
                "user_timeout":{
                    "type":"integer",
                    "minimum":200,
                    "maximum":60000
                }
            }
        }
    }
}

示例2:array、maxItems、maxLength

{
    "type":"object",
    "required":[
        "method",
        "rules"
    ],
    "properties":{
        "method":{
            "type":"string",
            "enum":[
                "replace"
            ]
        },
        "rules":{
            "type":"array",
            "maxItems":16,
            "items":{
                "required":[
                    "search_in",
                    "find",
                    "replace_with"
                ],
                "properties":{
                    "regex_enable":{
                        "type":"integer",
                        "enum":[
                            0,
                            1
                        ]
                    },
                    "search_in":{
                        "type":"string"
                    },
                    "find":{
                        "type":"string",
                        "minLength":1
                    },
                    "replace_with":{
                        "type":"string",
                        "minLength":1
                    }
                }
            }
        }
    }
}

示例3

{
    "type":"object",
    "required":[
        "method",
        "rules"
    ],
    "properties":{
        "method":{
            "type":"string",
            "enum":[
                "edit_element"
            ]
        },
        "rules":{
            "type":"array",
            "items":{
                "required":[
                    "anchor_element",
                    "target_element"
                ],
                "properties":{
                    "anchor_element":{
                        "type":"object",
                        "required":[
                            "search_scope",
                            "contained_keyword"
                        ],
                        "properties":{
                            "search_scope":{
                                "type":"string",
                                "enum":[
                                    "whole_file",
                                    "inside_element"
                                ]
                            },
                            "start_indicator":{
                                "type":"string"
                            },
                            "contained_keyword":{
                                "type":"string"
                            }
                        },
                        "if":{
                            "properties":{
                                "search_scope":{
                                    "const":"inside_element"
                                }
                            }
                        },
                        "then":{
                            "required":[
                                "start_indicator"
                            ]
                        }
                    },
                    "target_element":{
                        "type":"object",
                        "required":[
                            "target_distance_from_matching",
                            "element_treatment"
                        ],
                        "properties":{
                            "target_distance_from_matching":{
                                "type":"integer"
                            },
                            "element_treatment":{
                                "type":"string",
                                "enum":[
                                    "mark",
                                    "remove"
                                ]
                            }
                        }
                    }
                }
            }
        }
    }
}

四、networknt验证

<dependency>
    <groupId>com.networknt</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>1.0.76</version>
</dependency>
@Test
public void testNetworknt() {
    try {
        //可指定版本
        JsonSchemaFactory schemaFactory = JsonSchemaFactory
                .builder(com.networknt.schema.JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7))
                .objectMapper(new ObjectMapper())
                .build();
        JsonSchema schema = schemaFactory.getSchema(JsonMapper.fromJsonString(replaceSchema, JsonNode.class));
        Set<ValidationMessage> validate = schema.validate(JsonMapper.fromJsonString(repData, JsonNode.class));
        Iterator<ValidationMessage> iterator = validate.iterator();
        while (iterator.hasNext()){
            ValidationMessage next = iterator.next();
            System.out.println(next.getMessage());
        }
    }catch(Exception e ){
        e.printStackTrace();
    }
}

五、遇到的问题

  1. 示例3在验证下述json时,使用V202012版本,anchor_element.search_scope的value不在枚举列表中未报异常,但V7版本可以。

  1. Networknt要求使用的jaskson的版本在2.12.1以上,否则部分Json Schema属性无法使用,如maxItems、minLength。详见:https://github.com/networknt/json-schema-validator/issues/469

异常信息:

14:43:19.498 [main] DEBUG com.networknt.schema.PropertiesValidator - validate( {"name":"o"}, {"name":"o"}, $)
14:43:19.499 [main] WARN com.networknt.schema.JsonMetaSchema - Could not load validator minLength
com.networknt.schema.JsonSchemaException: java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.JsonNode.canConvertToExactIntegral()Z
    at com.networknt.schema.JsonMetaSchema.newValidator(JsonMetaSchema.java:293)
    at com.networknt.schema.ValidationContext.newValidator(ValidationContext.java:57)
    at com.networknt.schema.JsonSchema.read(JsonSchema.java:236)
    at com.networknt.schema.JsonSchema.getValidators(JsonSchema.java:524)
    at com.networknt.schema.JsonSchema.validate(JsonSchema.java:315)
    at com.networknt.schema.PropertiesValidator.validate(PropertiesValidator.java:69)
    at com.networknt.schema.JsonSchema.validate(JsonSchema.java:316)
    at com.networknt.schema.JsonSchema.validate(JsonSchema.java:299)
    at cn.nis.ntc.JsonValidate.testNetworknt(JsonValidate.java:92)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.JsonNode.canConvertToExactIntegral()Z

 类似资料: