spring - 从 springfox 迁移到 springdoc 时出现 Null ApiResponse

标签 spring swagger openapi springdoc

我正在尝试从 springfox-swagger2 (OpenAPI 2) 迁移到 springdoc-openapi-ui (OpenAPI 3),以生成 swagger 文档。

这是一个示例路线:

@RequestMapping("/api/object/")
public interface IObjectController {

    @RequestMapping(path = "v1/{param}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    ObjectDto getObjectByParamV1(@PathVariable("param") String code);
}

Swagger 生成与 springfox-swagger2 一起工作得很好,但是我在 springdoc 上遇到以下问题:

Null key for a Map not allowed in JSON (use a converting NullKeySerializer?)
(through reference chain: io.swagger.v3.oas.models.OpenAPI["paths"]->
io.swagger.v3.oas.models.Paths["/api/object/v1/{param}"]->io.swagger.v3.oas.models.PathItem["get"]->
io.swagger.v3.oas.models.Operation["responses"]->io.swagger.v3.oas.models.responses.ApiResponses["null"])

事实上,OpenAPI 尝试序列化以下对象:

responses: class ApiResponses {
            {null=class ApiResponse {
                description: default response
                headers: null
                content: class Content {
                    {*/*=class MediaType {
                        schema: class ComposedSchema {
                            class Schema {
                                type: null
                                format: null
                                $ref: null
                                description: null
                                title: null
                                multipleOf: null
                                maximum: null
                                exclusiveMaximum: null
                                minimum: null
                                exclusiveMinimum: null
                                maxLength: null
                                minLength: null
                                pattern: null
                                maxItems: null
                                minItems: null
                                uniqueItems: null
                                maxProperties: null
                                minProperties: null
                                required: null
                                not: null
                                properties: null
                                additionalProperties: null
                                nullable: null
                                readOnly: null
                                writeOnly: null
                                example: null
                                externalDocs: null
                                deprecated: null
                                discriminator: null
                                xml: null
                            }
                            allOf: null
                            anyOf: null
                            oneOf: [class Schema {
                                type: object
                                format: null
                                $ref: null
                                description: null
                                title: null
                                multipleOf: null
                                maximum: null
                                exclusiveMaximum: null
                                minimum: null
                                exclusiveMinimum: null
                                maxLength: null
                                minLength: null
                                pattern: null
                                maxItems: null
                                minItems: null
                                uniqueItems: null
                                maxProperties: null
                                minProperties: null
                                required: null
                                not: null
                                properties: null
                                additionalProperties: null
                                nullable: null
                                readOnly: null
                                writeOnly: null
                                example: null
                                externalDocs: null
                                deprecated: null
                                discriminator: null
                                xml: null
                            }, class StringSchema {
                                class Schema {
                                    type: string
                                    format: null
                                    $ref: null
                                    description: null
                                    title: null
                                    multipleOf: null
                                    maximum: null
                                    exclusiveMaximum: null
                                    minimum: null
                                    exclusiveMinimum: null
                                    maxLength: null
                                    minLength: null
                                    pattern: null
                                    maxItems: null
                                    minItems: null
                                    uniqueItems: null
                                    maxProperties: null
                                    minProperties: null
                                    required: null
                                    not: null
                                    properties: null
                                    additionalProperties: null
                                    nullable: null
                                    readOnly: null
                                    writeOnly: null
                                    example: null
                                    externalDocs: null
                                    deprecated: null
                                    discriminator: null
                                    xml: null
                                }
                            }]
                        }
                        examples: null
                        example: null
                        encoding: null
                    }}
                }
                links: null
                extensions: null
                $ref: null
            }, 200=class ApiResponse {
                description: OK
                headers: null
                content: class Content {
                    {application/json=class MediaType {
                        schema: class Schema {
                            type: null
                            format: null
                            $ref: #/components/schemas/ObjectDto
                            description: null
                            title: null
                            multipleOf: null
                            maximum: null
                            exclusiveMaximum: null
                            minimum: null
                            exclusiveMinimum: null
                            maxLength: null
                            minLength: null
                            pattern: null
                            maxItems: null
                            minItems: null
                            uniqueItems: null
                            maxProperties: null
                            minProperties: null
                            required: null
                            not: null
                            properties: null
                            additionalProperties: null
                            nullable: null
                            readOnly: null
                            writeOnly: null
                            example: null
                            externalDocs: null
                            deprecated: null
                            discriminator: null
                            xml: null
                        }
                        examples: null
                        example: null
                        encoding: null
                    }}
                }
                links: null
                extensions: null
                $ref: null
            }}
            extensions: null
        }

如您所见,ApiResponses 中有一个空的 ApiResponse 对象,奇怪的是它有一个 null 键,然后序列化在 jackon 中失败MapSerializer.serialize() :

// What is this _suppressNulls ?!
// _suppressableValue IS null, but is not suppressed
if ((_suppressableValue != null) || _suppressNulls) {
    serializeOptionalFields(value, gen, provider, _suppressableValue);
}

无论我使用多少 Swagger 注释(@Operation,添加 @ApiResponse...),这个 null ApiResponse 仍然存在。我不明白这是从哪里来的,特别是 suppressNull 只影响 values 而不是 keys,根据 MapSerializer.serializeOptionalFields()

如何删除这个 null 键控的 ApiResponse ?

最佳答案

看起来原因是在异常处理程序上没有@ExceptionHandler 上的@ResponseStatus。

解决方法是添加以便在 swagger 文档中显示它。

已经存在已修复的问题:

修复将在 v1.3.8 上可用。

关于spring - 从 springfox 迁移到 springdoc 时出现 Null ApiResponse,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61529174/

相关文章:

java - 如何使用 WebServiceTemplate 发送 SOAP 请求?

java - Spring MVC 形式的两个模型

java - 通过jetty.xml进行Swagger UI配置

c# - 如何在 AspNetCore 中定义 OpenApi 的文件响应

java - 我的 application.properties 文件中的属性显示为灰色,我无法配置数据源 : 'url' attribute is not specified

java - Spring MongoDB 查询正则表达式

rest - Swagger 响应类 Map

java - 如何从 OpenAPI 3.0 yaml 文件生成 JSON 示例?

postman - 如何验证组件模式中的嵌套属性(Postman 中的 openapi 3)

javascript - 通过参数而不是 formData 发送图像数组,如何更改它?