大家好,又见面了,我是你们的朋友全栈君。
何为Json-Schema Json-schema是描述你的JSON数据格式;JSON模式(应用程序/模式+ JSON)有多种用途,其中之一就是实例验证。验证过程可以是交互式或非交互式的。例如,应用程序可以使用JSON模式来构建用户界面使互动的内容生成除了用户输入检查或验证各种来源获取的数据。(来自百度百科)
相关jar包
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.2.6</version>
</dependency>
<!-- fasterxml -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.0</version>
</dependency>
package com.gaci;
import com.fasterxml.jackson.databind.JsonNode; import com.github.fge.jackson.JsonLoader; import com.github.fge.jsonschema.core.exceptions.ProcessingException; import com.github.fge.jsonschema.core.report.ProcessingMessage; import com.github.fge.jsonschema.core.report.ProcessingReport; import com.github.fge.jsonschema.main.JsonSchema; import com.github.fge.jsonschema.main.JsonSchemaFactory; import org.apache.commons.lang.ArrayUtils;
import javax.servlet.http.HttpServletRequest; import java.io.*; import java.util.Iterator;
/**
Created by Gaci on 2020/8/3. */ public class JSONSchemaUtil { // 创建订单请求JSON格式校验 private static String schema;
static {
// 获取创建订单格式校验
try {
String str = "";
// String filePath = JSONSchemaUtil.class.getResource(“/schema.json”).getPath();// src目录下 // filePath = filePath.substring(1); // InputStream in = new FileInputStream(new File(filePath)); InputStream in = new FileInputStream(new File(“E:\schema.json”)); BufferedReader reader = new BufferedReader(new InputStreamReader(in,“UTF-8”)); String line; while ((line = reader.readLine()) != null) { str += line; } schema = str; // System.out.println(schema); } catch (Exception e) { e.printStackTrace(); } }
private final static JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
/**
* 校验创建订单请求的格式
* @param mainSchema
* @param instance
* @return
* @throws IOException
* @throws ProcessingException
*/
// public static ProcessingReport validatorSchema(String mainSchema, String instance) throws IOException, ProcessingException {
public static String validatorSchema(String mainSchema, String instance) throws IOException, ProcessingException {
String error = "";
JsonNode mainNode = JsonLoader.fromString(mainSchema);
JsonNode instanceNode = JsonLoader.fromString(instance);
// com.fasterxml.jackson.databind.JsonNode mainNode = JsonLoader.fromString(mainSchema); // com.fasterxml.jackson.databind.JsonNode instanceNode = JsonLoader.fromString(instance);
JsonSchema schema = factory.getJsonSchema(mainNode);
ProcessingReport processingReport = schema.validate(instanceNode);
String s = processingReport.toString();
boolean flag = processingReport.isSuccess();
if(!flag){
error = convertMessage(processingReport,mainNode);
}
return error;
}
/***
*根据 report里面的错误字段,找到schema对应字段定义的中文提示,显示都前端
* @param report 校验json 的结果,里面包含错误字段,错误信息。
* @param schema 原始的schema文件。主要用来读取message,message中文信息
*/
private static String convertMessage(ProcessingReport report, JsonNode schema) {
String error = "";
Iterator<ProcessingMessage> iter = report.iterator();
ProcessingMessage processingMessage = null;
//保存校验失败字段的信息
JsonNode schemaErrorFieldJson = null;
//原始校验返回的信息
JsonNode validateResult = null;
while (iter.hasNext()) {
processingMessage = iter.next();
validateResult = processingMessage.asJson();
//keyword表示 一定是不符合schema规范
JsonNode keywordNode = validateResult.get("keyword");
// JsonNode nn = validateResult.get(“message”); JsonNode in = validateResult.get(“instance”); if (null != keywordNode) { //说明json validate 失败 String keyword = keywordNode.textValue();
schemaErrorFieldJson = findErrorField(schema, validateResult);
//keyword 如果是require说明缺少必填字段,取schema中 字段对应的message
if ("required".equalsIgnoreCase(keyword)) {
//如果是require,找到哪个字段缺少了
JsonNode missingNode = null;
if (null == schemaErrorFieldJson) {
missingNode = validateResult.get("message");
schemaErrorFieldJson = schema.get("properties").get(missingNode.get(0).textValue());
}
if (null != validateResult.get("message")) {
// Preconditions.checkArgument(false, validateResult.get(“message”).textValue()); // error += in.get(“pointer”).textValue()+”:”; error += validateResult.get(“message”).textValue(); } } else { //非必填校验失败。说明是格式验证失败。取schema中 字段对应的message if (null != validateResult.get(“message”)) { // Preconditions.checkArgument(false, validateResult.get(“message”).textValue()); error += in.get(“pointer”).textValue()+”:”; error += validateResult.get(“message”).textValue()+”;”; }
}
}
}
// System.out.println(error); return error; }
/***
* 根据校验结果的 schema pointer 中的url递归寻找JsonNode
* @param schema
* @param validateResult
* @return
*/
private static JsonNode findErrorField(JsonNode schema, JsonNode validateResult) {
//取到的数据是
String[] split = validateResult.get("schema").get("pointer").textValue().split("/");
JsonNode tempNode = null;
if (!ArrayUtils.isEmpty(split)) {
for (int i = 1; i < split.length; i++) {
if (i == 1) {
tempNode = read(schema, validateResult, split[i]);
} else {
tempNode = read(tempNode, validateResult, split[i]);
}
}
}
return tempNode;
}
private static JsonNode read(JsonNode jsonNode, JsonNode validateResult, String fieldName) {
return jsonNode.get(fieldName);
}
//获取请求体中的数据
// public String getStrResponse(){ // ActionContext ctx = ActionContext.getContext(); // HttpServletRequest request = (HttpServletRequest)ctx.get(ServletActionContext.HTTP_REQUEST); // InputStream inputStream; // String strResponse = “”; // try { // inputStream = request.getInputStream(); // String strMessage = “”; // BufferedReader reader; // reader = new BufferedReader(new InputStreamReader(inputStream,“utf-8”)); // while ((strMessage = reader.readLine()) != null) { // strResponse += strMessage; // } // reader.close(); // inputStream.close(); // } catch (IOException e) { // e.printStackTrace(); // } // return strResponse; // }
public static void main(String[] args){
try {
String str = "{\"name\":\"123\",\"sex\":\"男\"}";
String s = validatorSchema(schema, str);
System.out.println(s);
}catch (Exception e){
e.printStackTrace();
}
}
}
schema.json
{
"type": "object", // 类型 "properties": {
// 字段 "name": {
//name字段
"type": "string", // 类型string
"maxLength": 50,//最大长度
"pattern": "^[a-zA-Z0-9]*$"// 正则
}, "sex": {
"type": "string",
"maxLength": 20,
"pattern": "^[a-zA-Z0-9]*$"
}
},
"required": ["name","sex"] // 必填项
}
由于我填了中文,就提示错误,
提供一个带数组的json文件字段信息–描述
{
"type": "object", // 对象 "properties": {
// 字段 "usertoken": {
// token
"type": "string", // 字段类型
"maxLength": 50,// 最大长度
"pattern": "^[a-zA-Z0-9]*$" // 正则
}, "service": {
"type": "string",
"maxLength": 20,
"pattern": "^[a-zA-Z0-9]*$"
}, "paramJson": {
"type": "object", "required": ["orderNo"],// 当前对象必填 "properties": {
"orderNo": {
"type": "string",
"maxLength": 32,
"pattern": "^[a-zA-Z0-9]*$"
}, "declareItems": {
"type": "array", // 数组 "items": {
"type": "object", "required": ["ename"], "properties": {
"ename": {
"type": "string",
"maxLength": 100,
"pattern": "^[a-zA-Z0-9\\s]*$"
}
}
}
}
}
}
},
"required": ["usertoken","service"]
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/196216.html原文链接:https://javaforall.cn