javascript
利用JSON-schema校验请求报文,封装转换错误信息,提示前台
JSON-chema的语法就不讲述了,可自行查阅相关文档。
需求场景:前台请求接口的报文,为防止被非法拦截,需要后台再校验一遍报文合法性,之前都是在java代码中,用java代码来判断,查阅资料找到了json-schema-validate,一些基本简单的校验可以交给它来完成。
但是校验的具体哪个字段的提示信息不能以中文提示返回给前台,所以自己写了一个解析 校验结果的方法,来将检验结果错误信息以中文形式提示给前台。不多说,上代码
我的jsonschema配置文件 放在了/src/main/resources/json目录下
@Slf4j public class BaseJsonValidateUtil {private final static JsonSchemaFactory factory = JsonSchemaFactory.byDefault();/**** 根据定义的json schema 校验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, "未定义数据模板");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(), "请求数据格式非法");return report;}/**** 将json转换未 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;}/****根据 report里面的错误字段,找到schema对应字段定义的中文提示,显示都前端* @param report 校验json 的结果,里面包含错误字段,错误信息。* @param schema 原始的schema文件。主要用来读取empty_message,error_message中文信息*/private static void convertMessage(ProcessingReport report, JsonNode schema) {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");if (null != keywordNode) {//说明json validate 失败 String keyword = keywordNode.textValue();schemaErrorFieldJson = findErrorField(schema, validateResult);//keyword 如果是require说明缺少必填字段,取schema中 字段对应的empty_messageif ("required".equalsIgnoreCase(keyword)) {//如果是require,找到哪个字段缺少了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 {//非必填校验失败。说明是格式验证失败。取schema中 字段对应的error_messageif (null != schemaErrorFieldJson.get("error_message")) {log.error("validate field 【validate】 [{}] fail.", JSON.toJSON(schemaErrorFieldJson));Preconditions.checkArgument(false, schemaErrorFieldJson.get("error_message").textValue());}}}}}/**** 根据校验结果的 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);} }
所以功能都在ValidateJsonFormat 方法中完成
第一步:读取指定的schema文件
JsonNode schema = ReadJsonFromFileUtil.readJSONfile(jsonFileName);
第二步:将请求的json转换成JsonNode
JsonNode data = convertJsonToNode(params);
第三步:调用json-schema校验方法,校验是否合法
ProcessingReport report = factory.getValidator().validateUnchecked(schema, data);
第四步:将校验返回的结果解析,并将定义的empty_message,或者error_message 提示给前台
PS:这两个字段是自定义字段。非json-schema标准语法字段。所以检验结果中,会提示语法错误,但不影响我们使用
empty_message: 表示没有此字段,触发了required校验,会取此字段信息提示到前台
error_message: 表示不符合定义的校验规则(enum,maxlength,minlength,pattern等等),会取此字段中的中文提示
如果这两个字段为定义,则会触发
Preconditions.checkArgument(report.isSuccess(), "请求数据格式非法");
schema样例
controller
convertMessage方法说明: 此方法无法将 type: array类型的元素的错误信息以中文提示给前台。
@Slf4j 注解属于是lombok注解,编译器需要安装此插件。其余错误引入相关依赖即可
如果有什么好的想法,欢迎交流。
总结
以上是生活随笔为你收集整理的利用JSON-schema校验请求报文,封装转换错误信息,提示前台的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 树莓派的Perl 遨游之旅
- 下一篇: 转转转![Spring MVC] - 5