java - springdoc-openapi 如何在不更改 toString 的情况下使用 @JsonValue 枚举格式?

标签 java jackson swagger springdoc springdoc-openapi-ui

我有一个使用 springdoc-openapi 的 Spring Boot 应用程序为我的 Controller 生成 Swagger API 文档。 JSON 请求/响应中使用的枚举之一具有与其 value/toString() 不同的 JSON 表示形式。这是使用 Jackson @JsonValue 实现的。注释:

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

    @JsonValue
    private final String jsonValue;

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

但是,生成的 Swagger API 文档在列出时使用枚举值(特别是 toString() 的值)而不是 JSON 表示(根据 @JsonValue)枚举值:

{
  "openapi": "3.0.1",
  "info": { "title": "OpenAPI definition", "version": "v0" },
  "servers": [
    { "url": "http://localhost:8080", "description": "Generated server url" }
  ],
  "paths": { ... },
  "components": {
    "schemas": {
      "PlayingCard": {
        "type": "object",
        "properties": {
          "suit": {
            "type": "string",
            "enum": [ "Hearts", "Diamonds", "Clubs", "Spades" ]
          },
          "value": { "type": "integer", "format": "int32" }
        }
      }
    }
  }
}

有已关闭的问题 #1101在请求允许 @JsonValue 影响枚举序列化的 springdoc-openapi 项目中。然而,那个问题是closed因为没有为其提交 PR。

如何让枚举列表匹配 REST 端点接受/返回的实际 JSON 类型,而不是 toString() 值?

解决这个问题的第一个想法是使用 @Schema(allowableValues = {...}]来自 Swagger Core 的注释.但是,无论是错误还是设计,这都会添加到值列表中,而不是替换它:

@Schema(allowableValues = {"Hearts", "Diamonds", "Clubs", "Spades"})
public enum Suit {
    HEARTS("Hearts"), DIAMONDS("Diamonds"), CLUBS("Clubs"), SPADES("Spades");
    // ...
}
"suit": {
  "type": "string",
  "enum": [
    "HEARTS", 
    "DIAMONDS",
    "CLUBS",
    "SPADES",
    "Hearts",
    "Diamonds",
    "Clubs",
    "Spades"
  ]
}

可重现的例子

plugins {
    id 'org.springframework.boot' version '2.5.3'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'io.swagger.core.v3:swagger-annotations:2.1.10'
    implementation 'org.springdoc:springdoc-openapi-ui:1.5.10'
    implementation 'org.springframework.boot:spring-boot-starter-web'
}
package com.example.springdoc;

import com.fasterxml.jackson.annotation.JsonValue;

public class PlayingCard {
    private Suit suit;
    private Integer value;

    public Suit getSuit() { return suit; }
    public void setSuit(Suit suit) { this.suit = suit; }
    public Integer getValue() { return value; }
    public void setValue(Integer value) { this.value = value; }

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

        @JsonValue
        private final String jsonValue;

        Suit(String jsonValue) { this.jsonValue = jsonValue; }
    }
}
package com.example.springdoc;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/playingCard")
public class PlayingCardController {
    @PostMapping
    public PlayingCard echo(@RequestBody PlayingCard card) {
        return card;
    }
}

Swagger 网址:http://localhost:8080/v3/api-docs

最佳答案

由于错误 #3998Swagger Core , @JsonValue 在公共(public)方法上处理得当,但在字段上处理不当。因此,添加公共(public)访问器方法将按预期工作:

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

    private final String jsonValue;

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

    @JsonValue
    public String getJsonValue() {
        return jsonValue;
    }
}

关于java - springdoc-openapi 如何在不更改 toString 的情况下使用 @JsonValue 枚举格式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68747036/

相关文章:

java - 如何将对象添加到 JSONObject 而不转义内容

JsonView返回空的JSON对象

ruby-on-rails - 如何使用 grape swagger ui 传递数组?

go - 如何使用beego生成离线swagger文档

rest - 验证 OpenAPI 对 REST 设计最佳实践的合规性

java - 解析全名?

java - 使用JSOUP解析html文件并将其映射为JAVA中的键值对

java - Spring Boot 中 OffsetDateTime 的 jackson 日期格式

java - 何时以及为何使用缓冲输入和输出流?

java - 绑定(bind)用户实体和 GlassFish 主体