javascript
利用JSON-schema校验请求报文,封装转换错误信息,提示前台
JSON-chema的語法就不講述了,可自行查閱相關(guān)文檔。
需求場(chǎng)景:前臺(tái)請(qǐng)求接口的報(bào)文,為防止被非法攔截,需要后臺(tái)再校驗(yàn)一遍報(bào)文合法性,之前都是在java代碼中,用java代碼來判斷,查閱資料找到了json-schema-validate,一些基本簡(jiǎn)單的校驗(yàn)可以交給它來完成。
但是校驗(yàn)的具體哪個(gè)字段的提示信息不能以中文提示返回給前臺(tái),所以自己寫了一個(gè)解析 校驗(yàn)結(jié)果的方法,來將檢驗(yàn)結(jié)果錯(cuò)誤信息以中文形式提示給前臺(tái)。不多說,上代碼
我的jsonschema配置文件 放在了/src/main/resources/json目錄下
@Slf4j public class BaseJsonValidateUtil {private final static JsonSchemaFactory factory = JsonSchemaFactory.byDefault();/**** 根據(jù)定義的json schema 校驗(yàn)json格式* @param jsonFileName schema 文件名稱* @param params 傳遞的json 串*/public static ProcessingReport ValidateJsonFormat(String jsonFileName, JSONObject params) {log.info("recevie validate schema is {}, \n request params is \n {} ", jsonFileName, params);JsonNode schema = ReadJsonFromFileUtil.readJSONfile(jsonFileName);JsonNode data = convertJsonToNode(params);Preconditions.checkNotNull(schema, "未定義數(shù)據(jù)模板");Preconditions.checkNotNull(data, "缺少配置信息");ProcessingReport report = factory.getValidator().validateUnchecked(schema, data);//如果定義了empty_message 或者error_message 的話,將這些信息以異常的方式拋給前端convertMessage(report, schema);if (log.isDebugEnabled()) {log.debug("JsonSchema validate result {} \n", report);}Preconditions.checkArgument(report.isSuccess(), "請(qǐng)求數(shù)據(jù)格式非法");return report;}/**** 將json轉(zhuǎn)換未 JsonNode* @param paramsJson* @return*/private static JsonNode convertJsonToNode(JSONObject paramsJson) {JsonNode actualObj = null;try {ObjectMapper mapper = new ObjectMapper();actualObj = mapper.readTree(paramsJson.toJSONString());} catch (IOException e) {log.error("convertJsonToNode Exception!!! \n {}", e);return actualObj;}return actualObj;}/****根據(jù) report里面的錯(cuò)誤字段,找到schema對(duì)應(yīng)字段定義的中文提示,顯示都前端* @param report 校驗(yàn)json 的結(jié)果,里面包含錯(cuò)誤字段,錯(cuò)誤信息。* @param schema 原始的schema文件。主要用來讀取empty_message,error_message中文信息*/private static void convertMessage(ProcessingReport report, JsonNode schema) {Iterator<ProcessingMessage> iter = report.iterator();ProcessingMessage processingMessage = null;//保存校驗(yàn)失敗字段的信息JsonNode schemaErrorFieldJson = null;//原始校驗(yàn)返回的信息JsonNode validateResult = null;while (iter.hasNext()) {processingMessage = iter.next();validateResult = processingMessage.asJson();//keyword表示 一定是不符合schema規(guī)范JsonNode keywordNode = validateResult.get("keyword");if (null != keywordNode) {//說明json validate 失敗 String keyword = keywordNode.textValue();schemaErrorFieldJson = findErrorField(schema, validateResult);//keyword 如果是require說明缺少必填字段,取schema中 字段對(duì)應(yīng)的empty_messageif ("required".equalsIgnoreCase(keyword)) {//如果是require,找到哪個(gè)字段缺少了JsonNode missingNode = null;if (null == schemaErrorFieldJson) {missingNode = validateResult.get("missing");schemaErrorFieldJson = schema.get("properties").get(missingNode.get(0).textValue());}if (null != schemaErrorFieldJson.get("empty_message")) {log.error("validate field 【requeied】[{}] fail.", JSON.toJSON(schemaErrorFieldJson));Preconditions.checkArgument(false, schemaErrorFieldJson.get("empty_message").textValue());}} else {//非必填校驗(yàn)失敗。說明是格式驗(yàn)證失敗。取schema中 字段對(duì)應(yīng)的error_messageif (null != schemaErrorFieldJson.get("error_message")) {log.error("validate field 【validate】 [{}] fail.", JSON.toJSON(schemaErrorFieldJson));Preconditions.checkArgument(false, schemaErrorFieldJson.get("error_message").textValue());}}}}}/**** 根據(jù)校驗(yàn)結(jié)果的 schema pointer 中的url遞歸尋找JsonNode* @param schema* @param validateResult* @return*/private static JsonNode findErrorField(JsonNode schema, JsonNode validateResult) {//取到的數(shù)據(jù)是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);} }
所以功能都在ValidateJsonFormat 方法中完成
第一步:讀取指定的schema文件
JsonNode schema = ReadJsonFromFileUtil.readJSONfile(jsonFileName);
第二步:將請(qǐng)求的json轉(zhuǎn)換成JsonNode
JsonNode data = convertJsonToNode(params);
第三步:調(diào)用json-schema校驗(yàn)方法,校驗(yàn)是否合法
ProcessingReport report = factory.getValidator().validateUnchecked(schema, data);
第四步:將校驗(yàn)返回的結(jié)果解析,并將定義的empty_message,或者error_message 提示給前臺(tái)
PS:這兩個(gè)字段是自定義字段。非json-schema標(biāo)準(zhǔn)語法字段。所以檢驗(yàn)結(jié)果中,會(huì)提示語法錯(cuò)誤,但不影響我們使用
empty_message: 表示沒有此字段,觸發(fā)了required校驗(yàn),會(huì)取此字段信息提示到前臺(tái)
error_message: 表示不符合定義的校驗(yàn)規(guī)則(enum,maxlength,minlength,pattern等等),會(huì)取此字段中的中文提示
如果這兩個(gè)字段為定義,則會(huì)觸發(fā)
Preconditions.checkArgument(report.isSuccess(), "請(qǐng)求數(shù)據(jù)格式非法");
schema樣例
controller
convertMessage方法說明: 此方法無法將 type: array類型的元素的錯(cuò)誤信息以中文提示給前臺(tái)。
@Slf4j 注解屬于是lombok注解,編譯器需要安裝此插件。其余錯(cuò)誤引入相關(guān)依賴即可
如果有什么好的想法,歡迎交流。
總結(jié)
以上是生活随笔為你收集整理的利用JSON-schema校验请求报文,封装转换错误信息,提示前台的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 树莓派的Perl 遨游之旅
- 下一篇: 状态同步与帧同步的简介