JSON Schema 入门指南【Java后端使用】

时间:2024-03-01 20:21:31

使用场景

  后端接口获取到数据后,想看看数据是否符合我的标准,比如我想要的数据给没给我、值是不是我需要的类型……

  当然自己的系统一般会在前端做好数据校验,但是如果从别人的接口获取数据呢?谁知道他们会不会按照文档传来标准的数据呢?

JSON Schema 作用

  写一个json作为校验标准,通过schema对需要校验的json数据进行校验。校验数据的类型、大小、长度、……,子节点数据类型、大小、长度、……

示例

  我想要的数据需要符合以下条件:

    必须有nameagename是字符串,age是数字且只能等于10或者11sex是布尔。

  写成json并放入/static/json/test.json中:

{
    "title" : "Match test", 
    "description" : "This is a schema that matches test-jsons.",
    "type" : "object", /*type:类型 */
    "properties" : { /*propertie:成员们的校验条件*/
        "name" : {
            "type" : "string"       /*如果有name,它必须是字符串*/
        },
        "age" : {
                "type" : "number",      /*如果有age,它必须是数字*/
                "enum" : [10, 11]  /*enum:必须等于其中一个值 */
        },
        "sex": {
                "type" : "boolean"     /*如果有sex,它必须是布尔值*/
        }
    },
    "required": ["name", "age"] /*required:必须出现的成员*/
}

 PS  1: 可以放json文件里,也可以直接写在Java中,只要最后能用JSONObject拿到就好

    2:注释中的那种关键字有很多。可以根据想要验证的条件,在文档中自选关键字灵活运用。比如正则匹配、if-else等等

  Java中进行校验:

    public String test()
    {
        //map转换成json
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("name", "a");
        map.put("age", 10);
        JSONObject json = new JSONObject(map);//待校验的数据
       //从文件获取json
        InputStream test = getClass().getResourceAsStream("/static/json/test.json");
        JSONObject Schema = new JSONObject(new JSONTokener(test));//校验标准
        Schema schema = SchemaLoader.load(Schema);
        try {
            schema.validate(json);
       System.out.println("校验成功!");
        } catch (ValidationException e) {
            System.out.println(e.getAllMessages()); 
        }
        return "hello";
}

参考

  简介、关键字、在线工具:https://www.cnblogs.com/terencezhou/p/10474617.html

  基础关键字详细:https://www.jianshu.com/p/2b7a2b1d0c49

  ※※※详解:

    https://blog.csdn.net/swinfans/article/details/89231247?utm_medium=distribute.pc_relevant_download.none-task-blog-BlogCommendFromBaidu-1.nonecase&depth_1-utm_source=distribute.pc_relevant_download.none-task-blog-BlogCommendFromBaidu-1.nonecas

  官方Githttps://github.com/everit-org/json-schema

  官方文档:http://json-schema.org/learn/getting-started-step-by-step.html

引入

  pom.xml中添加:

    Java6/7 versions   tomcat7可以运行

    <dependency>
        <groupId>com.github.erosb</groupId>
        <artifactId>everit-json-schema-jdk6</artifactId>
        <version>1.9.2</version>
    </dependency>
    ……
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>                                

    最新版    tomcat7报错

    <dependency>
        <groupId>com.github.everit-org.json-schema</groupId>
        <artifactId>org.everit.json.schema</artifactId>
        <version>1.12.1</version>
    </dependency>
    ……
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>

运行

  校验标准同上,存放在test.json文件中。文件位置 /static/json/test.json.

  Java代码:

    Schema:自定义的校验标准json
    json1-5:待校验的json数据
    @PostMapping("/test")
    @ResponseBody
    public String test()
    {
        InputStream test = getClass().getResourceAsStream("/static/json/test.json");
        Map<String, Object> map1 = new HashMap<String, Object>();
        map1.put("name", "a");
        map1.put("age", 10);
        JSONObject json1 = new JSONObject(map1);
        
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("name", 1);
        map2.put("age", "12");
        JSONObject json2 = new JSONObject(map2);
        
        Map<String, Object> map3 = new HashMap<String, Object>();
        map3.put("name", "a");
        map3.put("sex", "0");
        JSONObject json3 = new JSONObject(map3);
        
        Map<String, Object> map4 = new HashMap<String, Object>();
        map4.put("name", "a"); 
        map4.put("age", 11);
        map4.put("sex", 0);
        JSONObject json4 = new JSONObject(map4);
        
        Map<String, Object> map5 = new HashMap<String, Object>();
        map5.put("name", "ad");
        map5.put("age", "12");
        map4.put("sex", 0);
        JSONObject json5 = new JSONObject(map5);
        
        JSONObject Schema = new JSONObject(new JSONTokener(test));
        Schema schema = SchemaLoader.load(Schema);
        System.out.println("—————————data1———————————");
        try {
            schema.validate(json1);
            System.out.println("校验成功!");
        } catch (ValidationException e) {
                System.out.println(e.getAllMessages()); 
        }

        System.out.println("—————————data2———————————"); 
        try {
            schema.validate(json2); 
            System.out.println("校验成功!");
        } catch (ValidationException e) {
            System.out.println(e.getAllMessages()); 
        }
         
        System.out.println("—————————data3———————————");
        try {
            schema.validate(json3);
            System.out.println("校验成功!");
        } catch (ValidationException e) {
                System.out.println(e.getAllMessages()); 
        }
        
        System.out.println("—————————data4———————————");
        try {
            schema.validate(json4);
            System.out.println("校验成功!");
        } catch (ValidationException e) {
                System.out.println(e.getAllMessages()); 
        }
        
        System.out.println("—————————data5———————————");
        try {
            schema.validate(json5);
            System.out.println("校验成功!");
        } catch (ValidationException e) {
                System.out.println(e.getAllMessages()); 
        }
        return "hello";
}

  打印结果:

—————————data1———————————
校验成功!
—————————data2———————————
[#/name: expected type: String, found: Integer, #/age: 12 is not a valid enum value, #/age: expected type: Number, found: String]
—————————data3———————————
[#: required key [age] not found, #/sex: expected type: Boolean, found: String]
—————————data4———————————
[#/sex: expected type: Boolean, found: Integer]
—————————data5———————————
[#/age: 12 is not a valid enum value, #/age: expected type: Number, found: String]