You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3.2.1迁移后Content-Type异常:Web服务控制器消费/生产错误

Spring Boot 2.4.5 迁移至3.2.1后的Content-Type处理异常及问题解答

迁移背景

将Spring Boot Web服务从2.4.5版本迁移至3.2.1版本后,原CRUD接口出现两类Content-Type处理异常:

问题1:POST/PUT请求异常

Servlet层自动将传入的Content-Type: application/json修改为Content-Type: application/json;charset=UTF-8,导致控制器方法无法匹配请求。即使显式在控制器方法上设置consumes="application/json;charset=UTF-8",问题仍未解决。

控制器POST方法示例:

@RequestMapping(value = "/voltagereading/",
                method = RequestMethod.POST,
                consumes = "application/json;charset=UTF-8",
                produces = MediaType.APPLICATION_JSON)
public @ResponseBody VoltageReading createVoltageReading(@RequestBody final VoltageReading newReading)  throws SQLException, Exception {
    // 方法实现
}

问题2:GET/DELETE请求异常

Servlet处理响应时错误地将Content-Type设为null,导致Jackson库无法找到对应的序列化转换器,无法将VoltageReading对象转为JSON。日志报错如下:

2024-01-17 10:09:33 ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/esp32service/api].[dispatcherServlet] Servlet.service() for servlet [dispatcherServlet] in context with path [/esp32service/api] threw exception [Request processing failed: org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class com.mdhlabs.esp32service.models.VoltageReading] with preset Content-Type 'null'] with root cause
org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class com.mdhlabs.esp32service.models.VoltageReading] with preset Content-Type 'null'

VoltageReading类具备无参构造函数,未配置JSON注解(在2.4.5版本可正常序列化)。尝试修改application.properties编码配置无效:

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force-response=true

问题解答

1. Spring Boot 3.2.1及Spring Core 6.1.13是否需额外注解以保持原JSON处理逻辑?

不需要额外注解。Spring Boot 3.x基于Spring 6,默认仍用Jackson作为JSON处理器,只要实体类符合Jackson序列化要求(如有无参构造、字段可访问),就能正常序列化/反序列化。迁移后出现问题,大概率是编码或请求/响应处理的配置变更导致,而非注解缺失。

2. 能否阻止Spring Boot向Content-Type头追加charset=UTF-8?

可以,有两种方式:

  • 自定义Jackson消息转换器:创建配置类,调整MappingJackson2HttpMessageConverter的支持媒体类型,避免添加charset:
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
        converters.add(0, converter);
    }
}
  • 调整Servlet编码配置:设置server.servlet.encoding.force=false,这样不会强制修改请求的Content-Type,但注意这会影响所有Servlet层面的编码处理,需根据场景权衡。

3. 为何显式配置application/json;charset=UTF-8仍无法匹配请求?

Spring MVC匹配consumes属性时会严格校验媒体类型的所有参数(包括charset),可能存在以下问题:

  • Servlet层修改后的Content-Type存在大小写、参数顺序差异;
  • 请求实际传入的Content-Type与配置仍不匹配;
  • 存在其他过滤器/拦截器修改请求头,导致最终到达控制器的Content-Type不符合预期。

更稳妥的方式是直接使用MediaType.APPLICATION_JSON_VALUE作为consumes值,它会自动匹配带或不带charset的application/json类型:

@RequestMapping(value = "/voltagereading/",
                method = RequestMethod.POST,
                consumes = MediaType.APPLICATION_JSON_VALUE,
                produces = MediaType.APPLICATION_JSON_VALUE)

4. 响应序列化时Content-Type为null的原因是什么?DAO已返回可序列化对象。

可能的原因包括:

  • 自定义拦截器/过滤器在处理响应时意外清空了Content-Type头;
  • 消息转换器配置异常,导致Spring无法确定响应媒体类型;
  • 仍在使用@Controller+@ResponseBody的老旧组合,Spring Boot 3.x推荐使用@RestController替代,确保响应处理逻辑正确;
  • 存在异常处理器或全局响应拦截器,干扰了响应头的设置。

建议先将控制器类改为@RestController并移除方法上的@ResponseBody,再排查是否有自定义Web组件修改响应头。若问题仍存在,可调试MappingJackson2HttpMessageConverter的write方法,查看Content-Type的设置过程。


内容的提问来源于stack exchange,提问作者mdhlabs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:53:25