Spring中相同响应不同返回方式为何输出不同错误?
问题解析:Spring MVC两种场景下无Getter类的错误响应差异
核心原因
问题本质是Spring MVC处理正常控制器返回值和异常处理器返回值时,错误处理路径完全不同——即便都是Jackson序列化失败,最终触发的响应逻辑也存在差异。
场景1:直接返回ErrorResponse触发406的流程
- 控制器方法
m1正常执行,返回ErrorResponse实例,进入正常返回值处理流程。 - Spring MVC根据请求的
Accept头(通常为application/json),匹配对应的HttpMessageConverter,这里选中MappingJackson2HttpMessageConverter。 - Jackson尝试序列化
ErrorResponse时,由于类的私有字段field和message未提供getter方法,且Jackson默认配置不允许直接访问私有字段,导致序列化失败。 - Spring MVC判定:没有任何
HttpMessageConverter能将返回值转换为客户端可接受的格式,完全符合HTTP 406(Not Acceptable)的语义,因此返回406错误响应。
场景2:异常处理器返回ErrorResponse触发500的流程
- 控制器方法抛出
ArithmeticException,被@ExceptionHandler注解的handleArithmeticException方法捕获,方法执行后返回ErrorResponse实例。 - 进入异常返回值处理流程,Spring同样尝试用
MappingJackson2HttpMessageConverter序列化返回值,同样因无getter导致序列化失败。 - 关键差异:异常处理阶段发生的序列化异常,会被Spring视为「处理异常时出现了新的异常」,此时Spring会放弃当前异常处理器的返回值,转而触发全局默认错误处理流程(由Spring Boot的
BasicErrorController处理)。 BasicErrorController生成包含500状态码的标准错误响应,也就是你看到的包含timestamp、status、error的JSON结构——这个响应和你返回的ErrorResponse完全无关,是Spring的默认错误输出。
验证补充
- 若给
ErrorResponse添加getter方法,两种场景都会正常返回{"field":"abc","message":"xxx"}格式的JSON,不会触发错误。 - 若修改Jackson配置允许直接访问私有字段,异常处理器会正常返回
ErrorResponse的JSON,而非默认500响应。
内容的提问来源于stack exchange,提问作者Vishal
相关产品推荐
相关产品推荐

