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

5gfr0r5j  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(290)

我正在开发一个基于服务的应用程序,我正在为该应用程序添加基于openapi的注解,例如@Schema中的@RequestBody, @Parameter, @Schema。我有一个example字段,我可以为该字段提供String的示例模板。
我已经提供了example JSON string,但是JSON内容太大了,所以我想从resources文件夹中的file添加它。但是我目前无法加载它。有人能告诉我如何从文件而不是字符串添加示例内容吗?
我试着看了一下,发现有一个字段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 {

}

我想将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"
        }))

我试图调查类似的问题,但提供的回答对我不起作用:

  1. How to refrence files in SpringDoc OpenAPI3?
  2. https://github.com/springdoc/springdoc-openapi/issues/1432
  3. https://github.com/springdoc/springdoc-openapi/issues/17
nzkunb0c

nzkunb0c1#

就我所知,ref值似乎期望一个可以找到架构的url?我看到有人建议创建一个端点来返回示例?这对我来说似乎有点过分...
我决定最简单的方法就是添加一些东西,从文件中提取示例并将它们插入OpenApi对象。
我在我的spring配置中实现了一个OpenApiCustomiser,这允许我指向apps resources文件夹中的文件以获取响应示例。
我对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")}) }) 
    })

要使上述内容正常工作,请添加以下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;
}

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

相关问题