给定一个 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#1244 和 swagger-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?
解决方案是告诉 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文档中:
要在生成的方法上添加注释,可以使用
。 [...] 有关更多详细信息,请参阅有关 onX 功能的文档。onMethod=@__({@AnnotationsHere})
语法有点奇怪,取决于您使用的 javac。
在 javac7 上,要使用 3 个功能中的任何一个,必须将要应用于onX
中的构造函数/方法/参数的注释包装起来。要应用多个注释,请使用@__(@AnnotationGoesHere)
。注释本身显然也可以有参数。@__({@Annotation1, @Annotation2})
在 javac8 及更高版本上,您可以在、onMethod
或onParam
后添加下划线。onConstructor
从
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; }
}