spring boot中gson替换jackson后httpmessageconverter失效,主因是自动配置冲突及gson对java 8时间、泛型擦除、string类型处理等不兼容;需手动注册并配置gsonhttpmessageconverter,调整顺序与适配器。

Spring Boot默认Jackson被Gson替换后HttpMessageConverter没生效
根本原因是Spring Boot的自动配置机制里,JacksonHttpMessageConvertersConfiguration和GsonHttpMessageConvertersConfiguration都通过@ConditionalOnMissingBean保护,但它们注册的HttpMessageConverter类型重叠(都是MappingJackson2HttpMessageConverter和GsonHttpMessageConverter),而Gson配置默认不启用——除非你显式引入gson依赖且没排除Jackson相关starter。
实操建议:
- 确认已添加
com.google.code.gson:gson依赖,且未意外引入spring-boot-starter-json(它会拉入Jackson并抢占优先级) - 在
application.properties中加spring.http.converters.preferred-json-mapper=gson(Spring Boot 2.3+才支持;旧版无效) - 更可靠的做法是手动注册:写一个
@Configuration类,@Bean返回GsonHttpMessageConverter,并确保它比Jackson的converter先加载(比如用@Order(Ordered.HIGHEST_PRECEDENCE))
手动注册GsonHttpMessageConverter时日期格式错乱
Gson默认不处理Java 8时间类型(LocalDateTime等),也不识别@JsonFormat注解,这和Jackson行为不一致,容易导致反序列化失败或格式错位。
实操建议:
- 构造
Gson实例时显式注册TimeOfDayTypeAdapter、LocalDateTimeTypeAdapter等自定义适配器 - 用
GsonBuilder.setDateFormat("yyyy-MM-dd HH:mm:ss")统一字符串日期解析格式 - 若需兼容
@JsonFormat(pattern = "..."),得自己写TypeAdapterFactory去读取该注解——这不是开箱即用的功能 - 避免直接复用Jackson的
ObjectMapper配置逻辑,Gson没有SerializationFeature或DeserializationFeature这类开关
GsonHttpMessageConverter不处理@RequestBody泛型擦除问题
比如接口定义为public Result<user> handle(@RequestBody Result<user> r)</user></user>,Gson默认反序列化会把User变成LinkedTreeMap,因为泛型信息在运行时已擦除,而GsonHttpMessageConverter没像Jackson那样集成TypeReference推导机制。
实操建议:
- 必须在controller方法里用
ParameterizedTypeReference配合RestTemplate调用时才起作用;对@RequestBody,Gson converter本身不支持泛型类型推导 - 解决方案只有两个:改用
Map<string object></string>接收再手动转,或在converter中覆写readInternal方法,借助ResolvableType.forMethodParameter提取真实泛型类型传给gson.fromJson(json, type) - 别指望
@JsonAdapter能自动解决这个层级的问题——它只管字段级,不管整个body的根类型
替换后ResponseEntity<string></string>返回空JSON或双引号包裹
这是最隐蔽的坑:当返回类型是String时,GsonHttpMessageConverter会把字符串当作JSON值序列化,比如返回"ok",结果变成"\"ok\""(带转义双引号);而Jackson默认把String当原始内容直接写出。
实操建议:
- 检查是否误将
GsonHttpMessageConverter放在了所有converter之前,它匹配String.class,导致原始字符串被当成JSON值处理 - 要么删掉
GsonHttpMessageConverter对String的支持:gsonConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON)),排除text/plain - 要么保留
StringHttpMessageConverter并确保它排在GsonHttpMessageConverter前面——顺序决定谁先“抢”到String类型
复杂点在于,converter顺序受@Order、@Primary、bean注册时机多重影响,调试时最好打日志看RequestMappingHandlerAdapter最终持有的messageConverters列表顺序。










