3

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

这是一个示例路线:

@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);
}

大摇大摆的一代工作得很好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
        }

如您所见,其中有一个空ApiResponse对象ApiResponses,奇怪的是有一个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...),这个nullApiResponse 仍然存在。我不明白这是从哪里来的,尤其是suppressNull只影响values而不是keys,根据MapSerializer.serializeOptionalFields()

如何删除此null键控 ApiResponse ?

4

2 回答 2

4

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

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

已经存在已修复的问题:

该修复程序将在 v1.3.8 上提供。

于 2020-05-01T10:54:50.627 回答
0

使用 v1.3.4 似乎对我来说效果很好。我在 v1.3.3 上并升级到最新的 v1.3.7 打破了一切。

我认为罪魁祸首是https://github.com/springdoc/springdoc-openapi/issues/597的修复

于 2020-05-01T02:30:38.580 回答