一个小问题:Swagger 不显示 VO,Swagger 泛型丢失

真正的原因是"SpringDoc 的坑"

⚠️ 结论

SpringDoc 在"静态工厂方法 + 嵌套泛型返回值"场景下,
有时无法正确推断 T 的真实类型

也就是说:

java 复制代码
public R<List<FriendVO>> listFriends() {
    return R.ok(friends);
}

Java 编译期是没问题的
运行期业务也是完全 OK 的

❌ 但 SpringDoc 在生成 OpenAPI Schema 时,推断失败

所以它只生成了:

复制代码
R
 └─ data: object

不会展开 FriendVO


为什么会这样?

  • Java 泛型 运行期会擦除

  • SpringDoc 主要靠:

    • 方法返回签名(返回类型)
    • 注解
    • 反射
  • 静态泛型工厂方法(R.ok(T data))是关键触发点

bash 复制代码
 Java 中完整方法签名 = 方法名 + 参数列表(类型、数量、顺序)
 而方法返回签名专指方法的返回值类型(注意:仅包含类型,不包含返回值名称 / 变量)

SpringDoc 有时候能推断

有时候推断不了(尤其是 R<List<VO>> 这种双层泛型)

👉 这是 SpringDoc 2.x 的已知行为


✅ 解决方案一(最推荐 )

👉 在 Controller 方法上 显式声明 Response Schema

java 复制代码
@Operation(
    summary = "查询我的好友列表",
    description = "传入当前登录用户ID,查询已成功建立好友关系的全部好友列表"
)
@ApiResponse(
    responseCode = "200",
    description = "成功",
    content = @Content(
        mediaType = "application/json",
        schema = @Schema(implementation = FriendVO.class)
    )
)
@GetMapping("/list")
public R<List<FriendVO>> listFriends(
        @NotNull @Min(1) @RequestParam Long userid) {
    return R.ok(friendService.getFriendList(userid));
}

🔥 这一行是"核按钮":

java 复制代码
@Schema(implementation = FriendVO.class)

📌 含义:
"别猜了,我明确告诉你 data 里装的是 FriendVO"


✅ 解决方案二(更优雅,适合多个接口)

R.data 加一个 @Schema 提示

你已经写了:

java 复制代码
@Schema(description = "业务数据载体,成功时返回具体业务数据,失败时为null,泛型适配任意类型数据")
private T data;

👉 但 SpringDoc 仍然不知道 T 是什么

可以加一个 泛型兜底(实战常用):

java 复制代码
@Schema(
    description = "业务数据",
    oneOf = { FriendVO.class }
)
private T data;

⚠️ 不过这个方式 适合单一业务域

如果 R 是全局通用,方案一更干净


✅ 解决方案三(调试 / 验证用,非最终)

加一个"直返 VO 的接口":

java 复制代码
@GetMapping("/_debug/friend-vo")
public FriendVO debugFriendVO() {
    return new FriendVO();
}

如果这个 能在 Schemas 里看到 FriendVO

👉 那就 100% 证明不是 VO / Lombok / 注解问题

相关推荐
程序员泠零澪回家种桔子19 分钟前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构
CodeCaptain27 分钟前
nacos-2.3.2-OEM与nacos3.1.x的差异分析
java·经验分享·nacos·springcloud
Anastasiozzzz1 小时前
Java Lambda 揭秘:从匿名内部类到底层原理的深度解析
java·开发语言
骇客野人1 小时前
通过脚本推送Docker镜像
java·docker·容器
铁蛋AI编程实战2 小时前
通义千问 3.5 Turbo GGUF 量化版本地部署教程:4G 显存即可运行,数据永不泄露
java·人工智能·python
晚霞的不甘2 小时前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
SunnyDays10112 小时前
使用 Java 冻结 Excel 行和列:完整指南
java·冻结excel行和列
摇滚侠2 小时前
在 SpringBoot 项目中,开发工具使用 IDEA,.idea 目录下的文件需要提交吗
java·spring boot·intellij-idea
云姜.2 小时前
java多态
java·开发语言·c++
李堇2 小时前
android滚动列表VerticalRollingTextView
android·java