HttpMediaTypeNotSupportedException本质是客户端Content-Type与服务端consumes声明或@RequestBody使用不匹配。需检查三处:客户端实际请求头、控制器consumes属性、是否遗漏@RequestBody;禁用混用@RequestBody与@RequestParam;Feign调用需显式设Content-Type头。

Spring Boot 接口报 HttpMediaTypeNotSupportedException 怎么快速定位
这个异常本质是客户端发来的请求体格式(Content-Type)和服务端控制器方法声明能接收的格式对不上。不是接口没写,也不是参数解析失败,而是“门牌号贴错了”——你标着只收 application/json,结果对方送来 application/x-www-form-urlencoded,Spring 直接拒收。
排查优先看三处:
- 客户端实际发出的
Content-Type请求头(用浏览器 DevTools 或curl -v确认) - Controller 方法上
@PostMapping或@PutMapping的consumes属性(比如consumes = "application/json") - 参数前是否漏了
@RequestBody(没它,Spring 默认按表单或查询参数解析,不走 JSON 反序列化)
@RequestBody 和 @RequestParam 混用导致的 HttpMediaTypeNotSupportedException
常见错误:前端用 fetch 发 JSON,后端却写成这样:
@PostMapping("/user")
public String save(@RequestParam String name, @RequestParam Integer age) { ... }
这时 Spring 会尝试把整个 JSON body 当作表单字段拆解,自然失败。根本原因在于:@RequestParam 对应的是 application/x-www-form-urlencoded 或 multipart/form-data,和 JSON 不兼容。
立即学习“Java免费学习笔记(深入)”;
正确做法分两路:
- 如果前端发的是 JSON(
Content-Type: application/json),后端必须用@RequestBody接收一个 POJO 或Map<String, Object> - 如果前端发的是表单数据,就别设
consumes = "application/json",也别加@RequestBody,保持@RequestParam即可 - 二者不能混在同一方法里——没有“既支持 JSON 又支持表单”的魔法注解
全局配置 WebMvcConfigurer 改 Content-Type 映射容易踩坑
有人想“一劳永逸”,在 configureContentNegotiation 里加 mediaType("json", MediaType.APPLICATION_JSON),但这解决不了 HttpMediaTypeNotSupportedException——它管的是返回值协商(Accept 头),不是请求体解析(Content-Type)。
真正影响请求体解析的是 HttpMessageConverter 链,尤其是 Jackson2ObjectMapperBuilder 和 StringHttpMessageConverter 的注册顺序。常见陷阱:
- 手动注册了自定义
MappingJackson2HttpMessageConverter,但没调用setSupportedMediaTypes显式支持application/json - 在
WebMvcConfigurer中覆盖了默认 converter,却忘了保留StringHttpMessageConverter对text/plain的支持,导致纯文本 POST 也报错 - Spring Boot 2.6+ 默认禁用
spring.mvc.contentnegotiation.favor-parameter=true,别指望靠?format=json绕过Content-Type校验
Feign 客户端调用时触发该异常的特殊原因
用 Feign 调第三方接口时,即使代码里写了 consumes = "application/json",也可能报这个错——因为 Feign 默认不自动设置 Content-Type 请求头,尤其当 @RequestBody 参数是 String 或 byte[] 时。
解决方案很直接:
- 用
@Headers("Content-Type: application/json")显式声明(最简单) - 如果参数是 POJO,确保 Feign 接口方法上标注了
consumes = "application/json",且引入了feign-jackson依赖 - 避免把 JSON 字符串直接塞进
@RequestBody String json;改用 POJO +@RequestBody,让 Feign 自动序列化并带上正确 header - 注意:Feign 的
produces控制响应解析,consumes才控制请求发送,别配反
这个异常表面看是格式问题,实际多数时候是前后端对“谁负责序列化”没对齐。只要盯住 Content-Type 请求头、@RequestBody 注解、以及 Feign/RestTemplate 的自动 header 行为这三点,基本不会卡住。










