欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > Spring Boot 自定义 HttpMessageConverter 导致 Swagger 文档无法访问的解决方案

Spring Boot 自定义 HttpMessageConverter 导致 Swagger 文档无法访问的解决方案

2025/4/1 4:02:02 来源:https://blog.csdn.net/m0_73774439/article/details/146492708  浏览:    关键词:Spring Boot 自定义 HttpMessageConverter 导致 Swagger 文档无法访问的解决方案

问题背景

在 Spring Boot 项目中,我们经常需要自定义 HttpMessageConverter 来处理 JSON 序列化,比如将 Long 类型转换为 String 以避免前端 JavaScript 的精度丢失问题。然而,当我们直接覆盖默认的 MappingJackson2HttpMessageConverter 时,可能会导致 Swagger 文档无法正常访问,返回空白页面或 JSON 解析错误。

问题复现

以下是一个典型的自定义 HttpMessageConverter 配置:

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();ObjectMapper objectMapper = new ObjectMapper();SimpleModule simpleModule = new SimpleModule();simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);simpleModule.addSerializer(Long.class, ToStringSerializer.instance);simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);objectMapper.registerModule(simpleModule);objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);jackson2HttpMessageConverter.setObjectMapper(objectMapper);converters.add(0, jackson2HttpMessageConverter); // 添加到首位
}

问题现象:

  • 访问 http://localhost:8080/swagger-ui.html 时,页面无法加载或显示异常。

  • 直接访问 http://localhost:8080/v3/api-docs/default 时,返回的 JSON 数据可能不符合 Swagger 的预期格式。

问题原因

  1. 覆盖默认转换器
    Spring Boot 默认会注册 MappingJackson2HttpMessageConverter,用于 JSON 序列化。当我们手动添加自定义转换器并放在首位(converters.add(0, ...)),会导致 Swagger 使用的默认转换器被跳过。

  2. ObjectMapper 配置冲突
    Swagger 依赖特定的 ObjectMapper 配置来生成 API 文档。如果我们修改了 ObjectMapper(如 Long 转 String),可能会破坏 Swagger 的 JSON 结构,导致文档无法正确渲染。

解决方案

方案 1:仅修改现有的 Jackson 转换器(推荐)

避免覆盖默认转换器,而是找到已存在的 MappingJackson2HttpMessageConverter 并修改其 ObjectMapper

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {for (HttpMessageConverter<?> converter : converters) {if (converter instanceof MappingJackson2HttpMessageConverter) {ObjectMapper objectMapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();configureObjectMapper(objectMapper);return;}}// 如果没找到,再添加新的转换器addNewJacksonConverter(converters);
}private void configureObjectMapper(ObjectMapper objectMapper) {SimpleModule module = new SimpleModule();module.addSerializer(BigInteger.class, ToStringSerializer.instance);module.addSerializer(Long.class, ToStringSerializer.instance);module.addSerializer(Long.TYPE, ToStringSerializer.instance);objectMapper.registerModule(module);objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}private void addNewJacksonConverter(List<HttpMessageConverter<?>> converters) {MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();ObjectMapper objectMapper = new ObjectMapper();configureObjectMapper(objectMapper);converter.setObjectMapper(objectMapper);converters.add(converter);
}

方案 2:动态判断请求路径,Swagger 请求走默认转换器

如果必须添加新的 HttpMessageConverter,可以动态判断请求路径,让 Swagger 请求仍然使用默认转换器:

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {ObjectMapper customObjectMapper = new ObjectMapper();SimpleModule module = new SimpleModule();module.addSerializer(BigInteger.class, ToStringSerializer.instance);module.addSerializer(Long.class, ToStringSerializer.instance);module.addSerializer(Long.TYPE, ToStringSerializer.instance);customObjectMapper.registerModule(module);customObjectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);MappingJackson2HttpMessageConverter customConverter = new MappingJackson2HttpMessageConverter(customObjectMapper) {@Overridepublic boolean canWrite(Class<?> clazz, MediaType mediaType) {// 如果是 Swagger 请求,则不使用自定义转换器ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attrs != null) {String path = attrs.getRequest().getRequestURI();if (path.startsWith("/v3/api-docs") || path.startsWith("/swagger-ui")) {return false; // 让默认转换器处理}}return super.canWrite(clazz, mediaType);}};converters.add(0, customConverter);
}

方案对比

方案优点缺点
修改现有转换器兼容性最好,不影响 Swagger需要确保默认转换器存在
动态路径判断灵活控制不同请求的转换逻辑需要依赖 RequestContextHolder

总结

  • 推荐使用方案 1(修改现有转换器),因为它不会破坏 Spring Boot 的默认行为,兼容性更好。

  • 如果必须新增转换器,可以使用 方案 2(动态路径判断),确保 Swagger 仍然能正常工作。

  • 最终目标是 让 Swagger 使用默认的 ObjectMapper,而业务接口使用自定义的 JSON 序列化规则

这样,既能解决前端 Long 精度问题,又能保证 Swagger 文档正常访问! 🚀


📌 欢迎在评论区讨论你的解决方案!
🔗 相关技术:Spring Boot、Swagger、HttpMessageConverter、ObjectMapper

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词