Spring Boot中Swagger UI展示含Proto POJO请求体的端点时卡顿
问题场景
我们基于Java 19、Spring Boot 3.0.5开发Web应用,使用org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2提供Swagger UI,遇到以下问题:
- 某接口以.proto文件生成的POJO作为
@RequestBody参数,访问该接口的Swagger UI页面时,浏览器出现卡顿甚至冻结 - 其他配置完全相同,但
@RequestBody为String类型的接口可正常访问Swagger UI - 该接口使用springfox作为Swagger实现时无异常,但springfox不兼容Spring Boot 3
- 已尝试重写
ProtobufJsonFormatHttpMessageConverter,但未解决问题,代码如下:
@Bean public ProtobufJsonFormatHttpMessageConverter protobufHttpMessageConverter() { return new ProtobufJsonFormatHttpMessageConverter(JsonFormat.parser().ignoringUnknownFields(), JsonFormat.printer().omittingInsignificantWhitespace()); }
解决方案
1. 关闭Swagger UI自动展开复杂模型
springdoc自动展开Protobuf生成的复杂POJO结构时,会导致浏览器渲染压力过高。通过全局配置关闭自动展开:
# 关闭模型自动展开,避免加载大量嵌套字段 springdoc.swagger-ui.default-model-expand-depth=-1 # 设置模型渲染模式为仅展示结构,不生成详细示例 springdoc.swagger-ui.default-model-rendering=model
2. 自定义Protobuf类型的Schema生成逻辑
springdoc默认的类型解析器对Protobuf生成的POJO处理不佳,可自定义转换器简化Schema结构:
@Bean public ModelConverter protobufModelConverter() { return new AbstractModelConverter() { @Override public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) { Class<?> clazz = type.getType(); // 识别Protobuf生成的类(继承GeneratedMessageV3) if (GeneratedMessageV3.class.isAssignableFrom(clazz)) { Schema schema = new Schema(); schema.setType("object"); // 手动添加需要在Swagger UI展示的字段,避免自动解析所有嵌套结构 schema.addProperty("keyField", new Schema<>().type("string")); schema.addProperty("valueField", new Schema<>().type("integer")); return schema; } return chain.hasNext() ? chain.next().resolve(type, context, chain) : null; } }; } // 注册自定义转换器 @Bean public ModelConverterProvider modelConverterProvider(List<ModelConverter> converters) { ModelConverterProvider provider = new ModelConverterProvider(); converters.forEach(provider::addConverter); return provider; }
3. 升级springdoc版本
旧版本springdoc可能存在Protobuf类型处理的bug,尝试升级到2.2.0及以上版本:
<!-- Maven依赖配置 --> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.2.0</version> </dependency>
内容的提问来源于stack exchange,提问作者Andrei Bulshtein
相关产品推荐
相关产品推荐

