使用JSON Schema验证器无法基于预定义YAML验证查询参数
查询参数JSON Schema校验失败问题解决
问题
基于预定义YAML文件中的Schema验证查询参数时,使用JSON Schema验证器校验失败。执行流程如下:
- 从OpenAPI中提取查询参数及其Schema并转换为JsonNode;
- 构造测试用查询参数Map并转换为JsonNode;
- 将YAML中的Schema转为JsonSchema并执行校验。
核心问题:步骤2生成的queryParameterSchema是Object类型,但YAML中定义的参数类型为String,导致TypeValidator始终返回false,无法正确构造步骤2的待校验节点。
代码片段
步骤1(提取OpenAPI查询参数Schema)
final List<Parameter> parameters = openAPI.getPaths().get(requestPath).getGet().getParameters() .stream().filter(parameter -> Objects.nonNull(parameter.getIn()) && parameter.getIn().equalsIgnoreCase("query")) .collect(Collectors.toList()); final Map<Parameter, JsonNode> parameterAndSchema = parameters.stream().collect(Collectors.toMap(Function.identity(), parameter -> { JsonNode parameterSchema; try { final Schema schema = parameter.getSchema(); parameterSchema = mapper.readTree(objectWriter.writeValueAsString(schema)); return parameterSchema; } catch (JsonProcessingException e) { throw new RuntimeException(e); } }));
步骤2(原错误构造待校验节点)
final Map<String,String> queryParameterMap = Map.of("test-parameter", "testValue1"); JsonNode queryParameterSchema = new ObjectMapper() .readTree(queryParameterMap,JsonNode.class);
步骤3(校验逻辑)
JsonSchemaFactory schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7); SchemaValidatorsConfig config = new SchemaValidatorsConfig(); config.setTypeLoose(true); config.setFailFast(false); JsonSchema jsonSchema = schemaFactory.getSchema(schema, config); processingReport = jsonSchema.validate(queryParameterSchema , queryParameterSchema , at);
示例YAML配置
paths: /test-instances: get: tags: - Instances (Store) summary: Test summary operationId: SearchInstances parameters: - name: test-parameter in: query description: Names of the services offered required: false style: form explode: false schema: type: string
解决思路
问题根源在于:你将整个查询参数Map转换成了Object类型的JsonNode(结构为{"test-parameter": "testValue1"}),但JSON Schema需要校验的是单个参数值的类型,而非包含参数的对象节点。
修正方案
针对每个查询参数单独提取对应的值,生成匹配Schema类型的JsonNode,再执行校验:
ObjectMapper mapper = new ObjectMapper(); final Map<String,String> queryParameterMap = Map.of("test-parameter", "testValue1"); // 遍历每个查询参数,逐一校验 for (Map.Entry<Parameter, JsonNode> entry : parameterAndSchema.entrySet()) { Parameter param = entry.getKey(); JsonNode paramSchemaNode = entry.getValue(); String paramName = param.getName(); // 获取参数值并转为String类型的JsonNode String paramValue = queryParameterMap.get(paramName); JsonNode paramValueNode = mapper.valueToTree(paramValue); // 构建JsonSchema并执行校验 JsonSchemaFactory schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7); SchemaValidatorsConfig config = new SchemaValidatorsConfig(); config.setTypeLoose(true); config.setFailFast(false); JsonSchema jsonSchema = schemaFactory.getSchema(paramSchemaNode, config); // 正确传入待校验节点 ProcessingReport processingReport = jsonSchema.validate(paramValueNode); // 处理校验结果 if (!processingReport.isSuccess()) { System.err.println("参数[" + paramName + "]校验失败: " + processingReport); } }
关键修正点
- 节点类型匹配:用
valueToTree直接将字符串参数转为String类型的JsonNode,和YAML中定义的string类型一致; - 校验对象正确:将单个参数值节点传入
validate方法,而非整个参数Map生成的Object节点; - 遍历逐一校验:对每个查询参数单独校验,符合OpenAPI中参数Schema的定义逻辑。
内容的提问来源于stack exchange,提问作者V John
相关产品推荐
相关产品推荐

