首页 前端知识 java 通过Json -schema完成对数据的效验

java 通过Json -schema完成对数据的效验

2024-05-24 08:05:54 前端知识 前端哥 199 336 我要收藏

Json -schema

  • 1.对象的效验
  • 2.数组套对象的效验
  • 3. 字符串的效验
    • 长度效验(minLength)(maxLength)
    • 正则效验
    • 日期和时间
  • 4.对象套对象效验
  • 5.对象套数组
  • 6. 其他参数
    • required(必须要填)
    • enum(范围之内)
    • not(不)
    • anyOf 和allOf(双方为真,有一个为真)
    • format
  • 7. $ref 的使用(定义全局枚举)

  • 参考文档
https://json-schema.org/understanding-json-schema/index.html

JSON Schema是什么?
根据JSON Schema 规范的定义,JSON模式是一种JSON媒体类型,用于定义JSON数据的结构。JSON模式旨在定义JSON数据的验证、文档、超链接导航和交互控制

  • 首先是添加pom

<!--        json格式效验测试-->
        <dependency>
            <groupId>com.github.everit-org.json-schema</groupId>
            <artifactId>org.everit.json.schema</artifactId>
            <version>1.9.2</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20180130</version>
        </dependency>
  • 先从最简单的对象的校验开始先了解其他语法在进一步逐一渗透

1.对象的效验

  • 接口测试
  • 这里说一下粗略的流程
1. 首先需要有一个需要进行效验的实体类
2. 通过JSON.toJSONString将其转为实体类
3.  getClass().getResourceAsStream是获取到json的配置文件
4. 将其变为new org.json.JSONObjec对象类型的数据,
5. 将我们 上面转为json的实体类变为 new  JSONObjec
6. 通过schema.validate()去进行文件的效验,如果正确返回true,否则直接抛异常
7. 后面就是将异常翻译一下传给前端,让用户知道是哪个格式出错了


import com.alibaba.fastjson.JSON;
import com.bj.cy.Service.bradnApiService;
import com.bj.cy.enity.brand;
import com.bj.cy.utils.CheckAnalysisList;
import com.bj.cy.utils.CheckRowVo;
import com.bj.cy.utils.nety.test1;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.everit.json.schema.ValidationException;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;



    @ApiOperation("检测数据效验")
    @RequestMapping(value = "test2", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    public Object test2(@RequestBody test1 test1) {
        //这个是你打算验证的JSON
        String userBehavioAudits = JSON.toJSONString(test1);
        //这个就是你设定的标准JSON
        InputStream inputStream = getClass().getResourceAsStream("/test.json");
        org.json.JSONObject Schema = new org.json.JSONObject(new JSONTokener(inputStream));
        org.everit.json.schema.Schema schema = SchemaLoader.load(Schema);
            try {
                JSONObject myJsonObject =  new  JSONObject(userBehavioAudits);
                schema.validate(myJsonObject);
            } catch (ValidationException e) {
                String errorMessage = e.getAllMessages().toString().replace("not found", "为空值!");
                String errorMessage1 = errorMessage.replace("is not a valid enum value", "不在枚举范围内!");
                String errorMessage2 = errorMessage1.replace("expected maxLength:", "字段最大长度为:");
                String errorMessage3 = errorMessage2.replace("actual:", "当前实际长度:");
                String errorMessage4 = errorMessage3.replace("is not less or equal to ", "最大范围为为:");
                String errorMessage5 = errorMessage4.replace("subject must not be valid against schema", "不可是以下枚举值");
                return  errorMessage5;
        }
        return "str";

    }

  • 实体类(test)
@Data
public class test1 {

    private String name;

    private  String sex;

    private String filename;
}
  • json效验文件
{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "http://example.com/example.json",
  "type": "object",
  "additionalProperties": true,
  "required": [
    "name",
    "sex",
    "filename"
  ],
  "properties": {
    "name": {
      "$id": "#/properties/name",
      "type": "string",
      "maxLength": 36,
      "minLength": 10,
      "not": {
        "enum": [
          "String",
          "string"
        ]
      }
    },
    "sex": {
      "$id": "#/properties/sex",
      "type": "string",
      "not": {
        "enum": [
          "String",
          "string"
        ]
      }
    },
    "filename": {
      "$id": "#/properties/filename",
      "type": "string",
      "not": {
        "enum": [
          "String",
          "string"
        ]
      }
    }
  }

}

在这里插入图片描述

在这里插入图片描述

2.数组套对象的效验

  • 数组套对象其实和上面的,没什么区别,for循环然后把错误信息add一下返回

    @ApiOperation("检测数据效验")
    @RequestMapping(value = "test3", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    public Object test3(@RequestBody List<test1> test1) {

        List<String>errLis=new ArrayList<>();

        //这个是你打算验证的JSON
        String userBehavioAudits = JSON.toJSONString(test1);

        //因为是数组所以要转为Jsonarrat类型的
        JSONArray array = new JSONArray(userBehavioAudits);
        //这个就是你设定的标准JSON

        InputStream inputStream = getClass().getResourceAsStream("/test.json");
        org.json.JSONObject Schema = new org.json.JSONObject(new JSONTokener(inputStream));
        org.everit.json.schema.Schema schema = SchemaLoader.load(Schema);
        for (int i = 0; i < test1.size(); i++) {


        try {
             JSONObject jsonObject = array.getJSONObject(i);
//            JSONObject myJsonObject =  new  JSONObject(userBehavioAudits);
            schema.validate(jsonObject);
        } catch (ValidationException e) {
            String errorMessage = e.getAllMessages().toString().replace("not found", "为空值!");
            String errorMessage1 = errorMessage.replace("is not a valid enum value", "不在枚举范围内!");
            String errorMessage2 = errorMessage1.replace("expected maxLength:", "字段最大长度为:");
            String errorMessage3 = errorMessage2.replace("actual:", "当前实际长度:");
            String errorMessage4 = errorMessage3.replace("is not less or equal to ", "最大范围为为:");
            String errorMessage5 = errorMessage4.replace("subject must not be valid against schema", "不可是以下枚举值");
            errLis.add(errorMessage5);
        }
        }
        return errLis;

    }

3. 字符串的效验

长度效验(minLength)(maxLength)

  • 效验最大长度是36,最小长度是10,在这个范围之内为true反之为false
    在这里插入图片描述
    在这里插入图片描述

正则效验

  • 效验其是否是一个邮箱
    在这里插入图片描述

在这里插入图片描述

日期和时间

  • “date-time”:日期和时间在一起,例如。2018-11-13T20:20:39+00:00
    “time”:草案 7 时间中的新内容,例如,20:20:39+00:00
    “date”:草案 7 日期中的新增内容,例如,.2018-11-13
    “duration”:2019-09 年草案中的新增内容 ISO 定义的持续时间 8601 ABNF 表示“持续时间”。为 例如,表示持续时间为 3 天

在这里插入图片描述
在这里插入图片描述

4.对象套对象效验

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "http://example.com/example.json",
  "type": "object",
  "additionalProperties": true,
  "required": [
    "shoop",
    "wor"
  ],
  "properties": {
    "shoop": {
      "$id": "#/properties/name",
      "type": "string",
      "maxLength": 5
    },
    "wor": {
      "$id": "#/properties/sex",
      "type": "string",
      "maxLength": 5
    },
    "test": {
      "type": "object",     //这个是主要的因为对象的类型是object类型
              "properties": {      
                "name": {
                  "type": "string",
                  "maxLength": 5
                }
              }
    }
  }

}

在这里插入图片描述

@Data
public class test2 {
    private String shoop;

    private String wor;

    private test1 test;
}

@Data
public class test1 {

    private String name;

    private  String sex;

    private String filename;
}

5.对象套数组

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "http://example.com/example.json",
  "type": "object",
  "additionalProperties": true,
  "required": [
    "shoop",
    "wor"
  ],
  "properties": {
    "shoop": {
      "$id": "#/properties/name",
      "type": "string",
      "maxLength": 5
    },
    "wor": {
      "$id": "#/properties/sex",
      "type": "string",
      "maxLength": 5
    },
    "test": {
      "type": "array",    //表名其是个数组
      "items": {   //表示每一个元素
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 5
          }
        }
      }
    }
  }

}

在这里插入图片描述

@Data
public class test3 {

    private String shoop;

    private String wor;

    private List<test1> test;
}
@Data
public class test1 {

    private String name;

    private  String sex;

    private String filename;
}

6. 其他参数

required(必须要填)

在这里插入图片描述
在这里插入图片描述

enum(范围之内)

在这里插入图片描述

在这里插入图片描述

not(不)

  • 增加了not的枚举是只有等于里面的数才会出错
    在这里插入图片描述
    在这里插入图片描述

anyOf 和allOf(双方为真,有一个为真)

  • anyOf 是有一个为真就可以
  • 反之则放行
    在这里插入图片描述

format

  • format关键字允许对常用的某些类型的字符串值进行基本语义验证:

/** 
format 的可能取值:
    "date-time":日期和时间在一起,例如, 2018-11-13T20:20:39+00:00。
    "time":draft7的时间,例如,20:20:39+00:00
    "date":draft7的日期,例如,2018-11-13。
    "hostname": Internet 主机名
    "idn-hostname":国际化 Internet 主机名
    "ipv4":IPv4 地址
    "ipv6":IPv6 地址
    "uri":通用资源标识符 (URI) 。
    "uri-reference":一个 URI 引用(URI 或相对引用)
    "iri":“uri”的国际化等价物。
    "iri-reference":“uri-reference”的国际化等价物
    "uri-template":一个 URI 模板(任何级别)
    "json-pointer":一个 JSON 指针
    "relative-json-pointer":一个相对 JSON 指针。
    "regex":正则表达式。
*/
 
{ 
  "type": "string", 
  "format": "date-time" 

7. $ref 的使用(定义全局枚举)

  • 首先,在 $defs 中定义了一个名为 “myEnumValues” 的结构,其中包含了所有可能的枚举值。然后,在 properties 中,我们使用 $ref 关键字引用了 “myEnumValues” 结构,同时将其应用于所有需要相同枚举值的参数。

    通过这种方式,你只需要在 myEnumValues 结构中定义所有的枚举值,就可以在需要的地方轻松重复使用,并且能够具备更好的可读性和维护性。

  • 看我如下代码,明显的是代码拢余了,每个都要写一样的东西,我们就可以使用,自定义结构
    在这里插入图片描述

  "$defs": {
    "myEnumValues": {
      "type": "string",
      "not":{
        "enum": ["string"]
      }
    }
    },

在这里插入图片描述

在这里插入图片描述

转载请注明出处或者链接地址:https://www.qianduange.cn//article/9350.html
标签
评论
发布的文章

用JS生成本周日期代码

2024-04-18 17:04:15

js 递归函数

2024-05-31 10:05:46

jQuery是什么?如何使用?

2024-03-12 01:03:24

js延迟加载的六种方式

2024-05-30 10:05:51

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!