OpenApi 如何从资源文件中为 @RequestBody -> @Content -> @Schema -> example 添加示例

BAT*_*008 8 java spring swagger swagger-ui openapi

我正在开发一个基于服务的应用程序,我正在为其添加openapi基于注释,例如@RequestBody, @Parameter, @Schema在“@Schema我有一个example字段”中,我可以为其提供格式示例模板String

我已经提供了,example JSON string但 JSON 内容很大,所以我想将其添加到file我的resources文件夹中。但我目前无法加载它。有人可以让我知道如何添加文件中的示例内容而不是字符串吗?

我尝试查找,发现有一个字段externalValue,但我无法理解如何使其工作。以下是文档的链接。

以下是我的代码,它工作得很好:

@Path("/generate")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RequestBody(description = "InputTemplate body",
        content = @Content(schema = @Schema(implementation = InputTemplate.class, example = "{\n" +
                "  \"names\":[\n" +
                "    \"Batman\",\n" +
                "    \"Superman\",\n" +
                "    \"Ironman\"\n" +
                "  ],\n" +
                "  \"jobs\":[\n" +
                "    \"Fighting\",\n" +
                "    \"Fyling\",\n" +
                "    \"Teching\"\n" +
                "  ]\n" +
                "}")))
public Multi<String> generate(final Map<String, Object> input) throws CustomException {
        
}
Run Code Online (Sandbox Code Playgroud)

我想用文件夹example中存在的外部文件的内容替换存在的 JSON 内容resources

在尝试了很多事情之后,我知道我需要使用@ExampleObject,但是如果我添加相应的注释并尝试打开我的注释Swagger UI,那么我将无法获取我添加的文件的内容。相反,它为我提供了来自 的数据InputTemplate.class

以下是修改后的代码:

@RequestBody(description = "InputTemplate body",
        content = @Content(schema = @Schema(implementation = InputTemplate.class), examples = {
                @ExampleObject(name = "Example-1",
                        description = "Example-1 for InputTemplate.",
                        ref = "#/resources/Example1.json"), externalValue = "#/resources/Example2.json"
                @ExampleObject(name = "Example-2",
                        description = "Example-2 for InputTemplate.",
                        ref = "#/resources/Example1.json") //externalValue = "#/resources/Example1.json"
        }))
Run Code Online (Sandbox Code Playgroud)

我尝试研究类似的问题,但提供的答复对我不起作用:

  1. 如何在 SpringDoc OpenAPI3 中引用文件?
  2. https://github.com/springdoc/springdoc-openapi/issues/1432
  3. https://github.com/springdoc/springdoc-openapi/issues/17

lee*_*tes 3

据我所知,ref 值似乎需要一个可以找到模式的 url?我看到有人建议创建一个端点来返回示例?这对我来说似乎有点太多了......

我决定最简单的事情就是添加一些内容来从文件中提取示例并将它们插入到 OpenApi 对象中。

OpenApiCustomiser在我的 spring 配置中实现了一个,这允许我指向应用程序资源文件夹中的文件以获取响应示例。

我这样注释 Controller 方法:

@ApiResponses(value = {
    @ApiResponse(responseCode = "200",
        content = { @Content(mediaType = "application/json", 
        schema = @Schema(implementation = SomeResponse.class, 
                  name = "YourResponse"),  
                  examples = {@ExampleObject(value = "@your_data_200_response.json")}) }) 
    })
Run Code Online (Sandbox Code Playgroud)

要使上述工作正常运行,您可以添加以下 OpenApiCustomiser 配置 bean:

@Bean
public OpenApiCustomiser applyStandardOpenAPIModifications() {
    return openApi -> {
        Paths paths = new Paths();
        openApi.getPaths().entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .forEach(stringPathItemEntry -> {
                    paths.addPathItem(stringPathItemEntry.getKey(), addExamples(stringPathItemEntry.getValue()));
                });
        openApi.setPaths(paths);
    };
}

private PathItem addExamples(PathItem pathItem) {
    if(pathItem.getPost() !=null)  {
        //Note you can also Do this to APIResponses to insert info from a file into examples in say, a 200 response.
            pathItem.getPost().getRequestBody().getContent().values().stream()
                    .forEach(c ->{
                        String fileName = c.getExample().toString().replaceFirst("@","");
                        ObjectNode node = null;
                        try {
                            //load file from where you want. also don't insert is as a string, it wont format properly
                            node = (ObjectNode) new ObjectMapper().readTree(methodToReadInFileToString(fileName)); 
                        } catch (JsonProcessingException e) {
                            throw new RuntimeException(e);
                        }
                        c.setExample(node);
                    }
            );
    }
    return pathItem;
}
Run Code Online (Sandbox Code Playgroud)

我只是从 /resources 中包含 .json 文件的文件夹加载文件。