1

这里需要注意的一点是,OpenAPI Schema 并未用于验证请求和响应的目的。OpenAPI 架构无法更改为常规 JSON 架构。

假设我们在表单中有一个 OpenAPI 模式

TestSchema.json

{
  "components": {
    "schemas": {
      "book": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "author": {
            "$ref": "#/components/schemas/author"
          }
        }
      },
      "author": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          }
        }
      }
    }
  }
}

现在假设我们有一些 JSON 采用上述模式中定义的“书”的形式

{
  "title": "LOTR",
  "author": {
    "name": "Tolkien"
  }
}

使用json-schema-validator库,我们编写了代码来执行此验证,如下所示

public class SchemaValidator {
    private final ObjectMapper mapper = new ObjectMapper();
    private final JsonSchema schema;

    public SchemaValidator(FileReader schemaFile) throws IOException {
        schema = getJsonSchemaFromJsonNode(mapper.readTree(schemaFile));
    }

    public Set<ValidationMessage> validate(String json) throws IOException {
        return schema.validate(mapper.readTree(json));
    }

    private JsonSchema getJsonSchemaFromJsonNode(JsonNode node) {
        return JsonSchemaFactory.getInstance(VersionFlag.V6).getSchema(node);
    }
}

用法:

@Test
void validate_invalidTitle() throws IOException {
    var schemaValidator = new SchemaValidator(
        new FileReader("src/test/resources/TestSchema.json")
    );
    var json = "{\"title\":5,\"author\":{\"name\":\"Tolkien\"}}";

    assertEquals(
        "$.title: integer found, string expected",
        schemaValidator.validate(json).stream().findAny().orElseThrow().getMessage()
    );
}

由于 OpenAPI 模式有两个额外的节点,"components"并且"schemas"此代码不执行验证,因为我们无法在我们的“书”json 和模式之间进行 1-1 验证。

解决此问题的一种方法是使用.findValue("book")

public SchemaValidator(FileReader schemaFile) throws IOException {
    schema = getJsonSchemaFromJsonNode(mapper.readTree(schemaFile).findValue("book"));
}

但这会导致错误

#/properties/author/$ref: Reference #/components/schemas/author cannot be resolved

因为我们现在已经破坏了参考路径。

解决此问题以通过测试的一种方法是$ref将架构中的 调整为#/author但架构本身无效。

我是否缺少此库中的工具或错误地构建对象?需要做什么才能使这个验证工作?

我在open-api-validator中进行了挖掘,最终使用该json-schema-validator库执行验证,但请求/响应验证不是我需要的步骤。

4

0 回答 0