一个小问题: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 / 注解问题

相关推荐
考虑考虑34 分钟前
JDK25模块导入声明
java·后端·java ee
_小马快跑_2 小时前
Java 的 8 大基本数据类型:为何是不可或缺的设计?
java
Re_zero4 小时前
线上日志被清空?这段仅10行的 IO 代码里竟然藏着3个毒瘤
java·后端
洋洋技术笔记4 小时前
Spring Boot条件注解详解
java·spring boot
程序员清风1 天前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
皮皮林5511 天前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java
华仔啊1 天前
挖到了 1 个 Java 小特性:var,用完就回不去了
java·后端
SimonKing1 天前
SpringBoot整合秘笈:让Mybatis用上Calcite,实现统一SQL查询
java·后端·程序员
日月云棠2 天前
各版本JDK对比:JDK 25 特性详解
java
用户8307196840822 天前
Spring Boot 项目中日期处理的最佳实践
java·spring boot