SpringMVC返回JSON报HttpMessageNotWritableException排查
你的判断成立,该异常由两类问题共同触发:一是Jackson依赖存在版本冲突、重复引入的问题,二是SpringMVC缺少必要的注解驱动配置,具体修复方案如下:
问题根因
- Jackson依赖配置错误:你重复引入了两个不同版本的
jackson-core,且Jackson三个核心包(core、annotations、databind)版本完全不统一,会导致类加载异常,Spring无法正常实例化Jackson的JSON消息转换器。额外引入的jackson-dataformat-xml是XML序列化依赖,对JSON转换无作用,版本不匹配还会加剧依赖冲突。 - SpringMVC配置缺失:你的servlet配置中没有添加
<mvc:annotation-driven/>标签。非SpringBoot环境下,该标签是自动注册JSON、请求参数解析等核心转换器的必要配置,缺失时哪怕Jackson依赖完全正确,Spring也不会加载JSON序列化组件,自然抛出找不到返回值转换器的异常。另外你配置中mvc对应的xsd路径写错了,会导致配置解析失败。 - 其他冗余/错误配置:你对存放实体类的
laustrup.models包做了组件扫描,实体类不需要被Spring容器管理,属于无效配置;Controller中手动new MailService的写法完全绕过了Spring容器,后续会出现依赖注入、事务失效等问题。
修复步骤
- 统一Jackson依赖版本
打开pom.xml,删除所有原有Jackson相关依赖,替换为版本完全一致的三个核心包,不需要XML返回功能的话直接删掉jackson-dataformat-xml依赖:
<!-- 先在properties节点中统一声明版本 --> <properties> <jackson.version>2.13.3</jackson.version> </properties> <dependencies> <!-- 原有spring-webmvc、servlet、jstl依赖保留不动,添加以下三个Jackson依赖 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> </dependencies>
- 修正SpringMVC servlet配置
打开DispatcherServlet对应的xml配置文件,修正mvc命名空间的xsd路径,添加<mvc:annotation-driven/>标签,删除models包的无效扫描:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:ctx="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 开启MVC注解驱动,自动注册JSON消息转换器、请求参数解析器 --> <mvc:annotation-driven/> <ctx:annotation-config/> <ctx:component-scan base-package="laustrup.controllers"/> <ctx:component-scan base-package="laustrup.services"/> <!-- 删除laustrup.models包的组件扫描配置,实体类不需要被Spring管理 --> </beans>
- 修正Controller的Service注入逻辑
不要手动new MailService实例,改为通过Spring依赖注入:
@RestController public class MailController { @Autowired private MailService service; // 删掉原有手动new Service的构造方法,其余接口代码保持不变 @RequestMapping("/hallo") public String halloWorld() { return "Hallo World!"; } @GetMapping(value = "/check_inbox", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public ResponseEntity<LinkedList<Mail>> checkInbox() { return service.checkInbox(); } @PutMapping(value = "put_in_mail", consumes = "application/json") public ResponseEntity<Mailbox> putInMailBox(@RequestBody Mail mail) { return service.putMailInInbox(mail); } @GetMapping("take_all_mail") public ResponseEntity<Mailbox> takeAllMail() { return service.takeMail(); } }
- 确认实体类序列化规则
确保Mail、Mailbox两个实体类提供无参构造方法,需要返回的字段都有对应public的getter方法,否则Jackson无法读取属性值会导致序列化失败。
所有修改完成后执行mvn clean package重新打包,将生成的war包重新部署到Tomcat并重启,接口即可正常返回JSON响应。
内容的提问来源于stack exchange,提问作者Laustrup
相关产品推荐
相关产品推荐

