如何配置Swagger生成带x-enum-varnames的枚举YAML?
问题:Swagger生成枚举YAML时保留枚举常量名与值的映射
场景描述
现有Java枚举类TileType,枚举常量名(如WALL)与对外暴露的标识符值(如"X")不一致:
package org.kurodev.progfrog.game.map; import com.fasterxml.jackson.annotation.JsonValue; import io.swagger.v3.oas.annotations.media.Schema; @Schema(enumAsRef = true) public enum TileType { WALL("X"), FLOOR("0"), VOID("#"), ; private final String identifier; TileType(String identifier) { this.identifier = identifier; } public static TileType identify(char s) { return identify(String.valueOf(s)); } public static TileType identify(String s) { for (TileType value : values()) { if (value.matches(s)) return value; } return null; } public static TileType identifyStrict(char s) { return identifyStrict(String.valueOf(s)); } public static TileType identifyStrict(String s) { for (TileType value : values()) { if (value.matches(s)) return value; } throw new MapValidationException("Unrecognised tile: " + s); } @JsonValue public String getIdentifier() { return identifier; } private boolean matches(String s) { return s.equals(identifier); } }
当前Swagger生成结果
- 保留
@JsonValue注解时,生成的YAML仅包含标识符值:
TileType: type: string enum: - X - "0" - '#'
- 移除
@JsonValue注解时,生成的YAML仅包含常量名的驼峰形式:
TileType: type: string enum: - Wall - Floor - Void
期望生成的YAML结构
需要生成包含x-enum-varnames扩展的YAML,关联枚举常量名与对应标识符值:
TileType: type: string enum: - X - "0" - '#' x-enum-varnames: - WALL - FLOOR - VOID
期望生成的TypeScript客户端枚举
希望TypeScript客户端生成如下结构,而非自动生成的不合理键名:
export const TileType = { WALL: 'X', FLOOR: '0', VOID: '#' } as const;
当前生成的不合理结构:
export const TileType = { X: 'X', _0: '0', Hash: '#' } as const;
已尝试的方案
- 组合使用
@Schema、@JsonProperty、@JsonValue、@JsonCreator、@JsonSerialize等注解,均未达到预期效果。 - 自定义
ModelConverter类,已确认代码被调用且扩展已写入,但生成的YAML中未包含该扩展:
@Component public class CustomEnumConverter implements ModelConverter { private final ModelResolver defaultConverter; @Autowired public CustomEnumConverter(ObjectMapper objectMapper) { this.defaultConverter = new ModelResolver(objectMapper); } @Override public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) { Schema model = defaultConverter.resolve(type, context, chain); if (type.getType().getTypeName().contains(TileType.class.getName())) { model.addExtension("x-enum-varnames", Arrays.toString(TileType.values())); } return model; } }
内容的提问来源于stack exchange,提问作者Kuro-dev
相关产品推荐
相关产品推荐

