请求体解析失败报 HttpMessageNotReadableException,到底哪里错了?哪些看着不对的请求体其实能通过?客户端能看到什么?这篇在 Spring Boot 4.0.8 上把 22 种请求体逐个发一遍。
共 22 种请求体,返回 200 的 5 种,返回 400 等的 17 种
能通过:数字字符串 {"n":"1"} 传给 int → ok n=1 s=null d=null c=null l=null b=false
能通过:小数 {"n":1.5} 传给 int → ok n=1 s=null d=null c=null l=null b=false
能通过:开头带 BOM → ok n=1 s=null d=null c=null l=null b=false
能通过:重复的键 {"n":1,"n":2} → ok n=2 s=null d=null c=null l=null b=false
能通过:多余的未知字段 {"zzz":1} → ok n=0 s=null d=null c=null l=null b=false数字字符串、1.5 截断、BOM、重复键、未知字段都被接受。
请求体为空 → 400;HttpMessageNotReadableException → 最内层 HttpMessageNotReadableException:Required request body is missing: public java.lang.String demo.Main.p(demo.Dto)
JSON 语法错误 {bad → 400;HttpMessageNotReadableException → 最内层 StreamReadException:Unexpected character ('b' (code 98)): was expecting double-quote to start property name
字符串传给 int 字段 {"n":"abc"} → 400;HttpMessageNotReadableException → 最内层 InvalidFormatException:Cannot deserialize value of type `int` from String "abc": not a valid `int` value
null 传给 int 字段 {"n":null} → 400;HttpMessageNotReadableException → 最内层 MismatchedInputException:Cannot map `null` into type `int` (set `DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES` to 'false' to allow)
数值溢出 {"n":99999999999} → 400;HttpMessageNotReadableException → 最内层 InputCoercionException:Numeric value (99999999999) out of range of `int` (-2147483648 - 2147483647)
枚举值不存在 {"c":"BLUE"} → 400;HttpMessageNotReadableException → 最内层 InvalidFormatException:Cannot deserialize value of type `demo.Color` from String "BLUE": not one of the values accepted for Enum class: [RED, GREEN]
日期格式不对 {"d":"2026/10/23"} → 400;HttpMessageNotReadableException → 最内层 DateTimeParseException:Text '2026/10/23' could not be parsed at index 4
字符串传给 List {"l":"x"} → 400;HttpMessageNotReadableException → 最内层 MismatchedInputException:Cannot deserialize value of type `java.util.ArrayList<java.lang.Integer>` from String value (token `JsonToken.VALUE_STRING`)
List 里元素类型不对 {"l":[1,"a"]} → 400;HttpMessageNotReadableException → 最内层 InvalidFormatException:Cannot deserialize value of type `java.lang.Integer` from String "a": not a valid `java.lang.Integer` value
布尔值写成 "yes" {"b":"yes"} → 400;HttpMessageNotReadableException → 最内层 InvalidFormatException:Cannot deserialize value of type `boolean` from String "yes": only "true"/"True"/"TRUE" or "false"/"False"/"FALSE" recognized
对象传给 String {"s":{"a":1}} → 400;HttpMessageNotReadableException → 最内层 MismatchedInputException:Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`)
数组传给对象 [1,2] → 400;HttpMessageNotReadableException → 最内层 MismatchedInputException:Cannot deserialize value of type `demo.Dto` from Array value (token `JsonToken.START_ARRAY`)
末尾多余逗号 {"n":1,} → 400;HttpMessageNotReadableException → 最内层 StreamReadException:Unexpected character ('}' (code 125)): was expecting double-quote to start property name
单引号 {'n':1} → 400;HttpMessageNotReadableException → 最内层 StreamReadException:Unexpected character (''' (code 39)): was expecting double-quote to start property name
带注释 {"n":1 /*x*/} → 400;HttpMessageNotReadableException → 最内层 StreamReadException:Unexpected character ('/' (code 47)): maybe a (non-standard) comment? (not recognized as one since Feature 'ALLOW_COMMENTS' not enabled for parser)
后面多一个 JSON {"n":1}{"n":2} → 400;HttpMessageNotReadableException → 最内层 MismatchedInputException:Trailing token (`JsonToken.START_OBJECT`) found after value (bound as `demo.Dto`): not allowed as per `DeserializationFeature.FAIL_ON_TRAILING_TOKENS`
非法的 UTF-8 字节 → 400;HttpMessageNotReadableException → 最内层 StreamReadException:Invalid UTF-8 start byte 0xff顶层同一个异常,最内层按语法、类型、范围分成几类。
JSON 语法错误 {bad → 响应体 {"timestamp":"2026-10-23T07:42:38.554Z","status":400,"error":"Bad Request","path":"/p"}
字符串传给 int 字段 {"n":"abc"} → 响应体 {"timestamp":"2026-10-23T07:42:38.557Z","status":400,"error":"Bad Request","path":"/p"}
null 传给 int 字段 {"n":null} → 响应体 {"timestamp":"2026-10-23T07:42:38.568Z","status":400,"error":"Bad Request","path":"/p"}
枚举值不存在 {"c":"BLUE"} → 响应体 {"timestamp":"2026-10-23T07:42:38.572Z","status":400,"error":"Bad Request","path":"/p"}
开启 spring.mvc.problemdetails.enabled=true 之后:JSON 语法错误 {bad → 400 {"detail":"Failed to read request","instance":"/p","status":400,"title":"Bad Request"}
开启 spring.mvc.problemdetails.enabled=true 之后:字符串传给 int 字段 {"n":"abc"} → 400 {"detail":"Failed to read request","instance":"/p","status":400,"title":"Bad Request"}
开启 spring.mvc.problemdetails.enabled=true 之后:null 传给 int 字段 {"n":null} → 400 {"detail":"Failed to read request","instance":"/p","status":400,"title":"Bad Request"}
开启 spring.mvc.problemdetails.enabled=true 之后:枚举值不存在 {"c":"BLUE"} → 400 {"detail":"Failed to read request","instance":"/p","status":400,"title":"Bad Request"}响应体不带具体原因,要自己提取。