You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swagger UI文档无法显示鉴别器type可选值的问题求助

问题描述

我希望在Swagger UI的API文档中,让Conversion和Analysis这两个可选值显示在响应Schema的type字段中。我的API返回TaskOutput类型对象,其中data字段是两种类型之一。目前Swagger UI里仅能看到type属性被标记为必填字符串类型,导致API使用者无法知晓type字段的具体取值选项——尽管实际响应的序列化格式是正确的,但文档信息不完整。

我的代码如下:

public class TaskOutput {
    
    private TaskDataOutput data;

    @JsonProperty("data")
    @Schema(name = "data", oneOf = {
            AnalysisTaskDataOutput.class,
            ConversionTaskDataOutput.class
    })
    public TaskDataOutput getData() {
        return data;
    }

}

public class AnalysisTaskDataOutput implements TaskDataOutput {

    private Boolean cleanup;

    @Schema(name = "cleanup")
    @JsonProperty("cleanup")
    public Boolean getCleanup() {
        return cleanup;
    }

}

public class ConversionTaskDataOutput implements TaskDataOutput {

    private Boolean converted;

    @Schema(name = "converted")
    @JsonProperty("converted")
    public Boolean getConverted() {
        return converted;
    }
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = AnalysisTaskDataOutput.class, name = "Analysis"),
        @JsonSubTypes.Type(value = ConversionTaskDataOutput.class, name = "Conversion"),
})
public interface TaskDataOutput {
}

我尝试过创建包含Analysis和Conversion的枚举,并在接口中定义DataType getType()方法,但Swagger UI里还是不显示这些可选值。


解决方案

Swagger默认不会自动读取Jackson多态注解里的类型名称,需要通过以下两种方式让type字段的可选值显示在文档中:

方案1:在接口中显式定义带约束的type方法

修改TaskDataOutput接口,添加getType()方法并通过@Schema指定允许的取值,同时在实现类中返回对应类型名称:

import io.swagger.v3.oas.annotations.media.Schema;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = AnalysisTaskDataOutput.class, name = "Analysis"),
        @JsonSubTypes.Type(value = ConversionTaskDataOutput.class, name = "Conversion"),
})
public interface TaskDataOutput {

    @Schema(name = "type", allowableValues = {"Analysis", "Conversion"}, required = true)
    String getType();
}

实现类补充方法:

public class AnalysisTaskDataOutput implements TaskDataOutput {

    private Boolean cleanup;

    @Schema(name = "cleanup")
    @JsonProperty("cleanup")
    public Boolean getCleanup() {
        return cleanup;
    }

    @Override
    public String getType() {
        return "Analysis";
    }
}

public class ConversionTaskDataOutput implements TaskDataOutput {

    private Boolean converted;

    @Schema(name = "converted")
    @JsonProperty("converted")
    public Boolean getConverted() {
        return converted;
    }

    @Override
    public String getType() {
        return "Conversion";
    }
}

方案2:自定义转换器自动解析Jackson多态注解

如果不想改动业务代码,可以通过自定义ModelConverter让Swagger自动读取@JsonSubTypes中的类型名称:

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.swagger.v3.core.converter.ModelConverter;
import io.swagger.v3.core.converter.ModelConverterContext;
import io.swagger.v3.oas.models.media.Schema;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class JacksonPolymorphismModelConverter implements ModelConverter {

    @Override
    public Schema resolve(Type type, ModelConverterContext context, Iterator<ModelConverter> chain) {
        Schema schema = chain.hasNext() ? chain.next().resolve(type, context, this) : null;
        if (schema == null || !(type instanceof Class)) {
            return schema;
        }

        Class<?> clazz = (Class<?>) type;
        JsonTypeInfo typeInfo = clazz.getAnnotation(JsonTypeInfo.class);
        if (typeInfo != null && typeInfo.use() == JsonTypeInfo.Id.NAME) {
            JsonSubTypes subTypes = clazz.getAnnotation(JsonSubTypes.class);
            if (subTypes != null && subTypes.value().length > 0) {
                List<String> allowableValues = List.of(subTypes.value()).stream()
                        .map(JsonSubTypes.Type::name)
                        .collect(Collectors.toList());
                
                // 给type字段设置枚举值和描述
                schema.getProperties().get(typeInfo.property())
                        .setEnum(allowableValues)
                        .setDescription("任务类型:" + String.join("、", allowableValues));
            }
        }
        return schema;
    }
}

这个转换器会自动扫描带Jackson多态注解的接口,把@JsonSubTypes里的类型名称同步到Swagger的Schema中,无需修改业务类。


内容的提问来源于stack exchange,提问作者DArkO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:45:30