如何使用带有 Lombok getter 的 springdoc-openapi 将 @JsonValue 用于 Swagger 枚举值

问题描述 投票:0回答:2

给定一个 Spring Boot 项目,该项目使用 springdoc-openapi 库公开一个 OpenAPI (Swagger) 端点,记录项目的 Spring MVC 控制器端点。

项目中的一个枚举在字段上使用来自 Jackson

@JsonValue 来更改枚举的 JSON 表示形式。该枚举字段使用 Project Lombok
 中的 
@Getter 注释公开为 getter:

@Getter
public enum Suit {
    HEARTS("Hearts"), DIAMONDS("Diamonds"), CLUBS("Clubs"), SPADES("Spades");

    @JsonValue
    private final String name;

    Suit(String name) { this.name = name; }
}

但是,尽管 Jackson 表示基于字段,但 OpenAPI 端点返回的枚举表示使用

toString
enum
值来代替:

"suit": {
  "type": "string",
  "enum": [
    "HEARTS",
    "DIAMONDS",
    "CLUBS",
    "SPADES"
  ]
}

预期:

"suit": {
  "type": "string",
  "enum": [
    "Hearts",
    "Diamonds",
    "Clubs",
    "Spades"
  ]
}

基于 springdoc-openapi#1244swagger-core#3998,很明显

@JsonValue
注释需要应用于方法,而不是字段。然而,上述尝试的方法和以下方法都不起作用:

@Getter @JsonValue
public enum Suit {
    HEARTS("Hearts"), DIAMONDS("Diamonds"), CLUBS("Clubs"), SPADES("Spades");

    private final String name;

    Suit(String name) { this.name = name; }
}

如何在 Swagger 中使用正确的值公开此枚举,同时仍然使用 Lombok 生成 getter?

java jackson swagger lombok springdoc
2个回答
1
投票

解决方案是告诉 Lombok 在生成的 getter 方法上使用注释,在字段上使用

@Getter(onMethod_ = @JsonValue)

public enum Suit {
    HEARTS("Hearts"), DIAMONDS("Diamonds"), CLUBS("Clubs"), SPADES("Spades");

    @Getter(onMethod_ = @JsonValue)
    private final String name;

    Suit(String name) { this.name = name; }
}

onMethod
属性记录在@Getter和@Setter以及onX文档中:

要在生成的方法上添加注释,可以使用

onMethod=@__({@AnnotationsHere})
。 [...] 有关更多详细信息,请参阅有关 onX 功能的文档。

语法有点奇怪,取决于您使用的 javac。
在 javac7 上,要使用 3 个

onX
功能中的任何一个,必须将要应用于
@__(@AnnotationGoesHere)
中的构造函数/方法/参数的注释包装起来。要应用多个注释,请使用
@__({@Annotation1, @Annotation2})
。注释本身显然也可以有参数。
在 javac8 及更高版本上,您可以在
onMethod
onParam
onConstructor
后添加下划线。


0
投票

swagger-core
2.2.5 开始,swagger-core#3998 问题已得到解决,基于字段的注释应该可以工作。 Springdoc 1.6.13 及更高版本使用此版本。

@Getter
public enum Suit {
    HEARTS("Hearts"), DIAMONDS("Diamonds"), CLUBS("Clubs"), SPADES("Spades");

    @JsonValue
    private final String name;

    Suit(String name) { this.name = name; }
}
© www.soinside.com 2019 - 2024. All rights reserved.