Spring Boot REST API报错:HttpMessageNotWritableException求助
我之前写Spring Boot REST接口的时候也碰到过一模一样的问题,这个异常Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class java.util.LinkedHashMap,本质是Spring没法确定返回对象的序列化规则,或者缺少必要的依赖/配置,导致无法把返回结果转换成HTTP响应体。下面是几个最常见的解决思路:
1. 明确ResponseEntity的泛型类型
你的方法返回的是ResponseEntity但没有指定泛型,Spring没法提前知道要序列化的具体对象类型,内部可能会把它转成LinkedHashMap,进而找不到合适的转换器。
修正代码:把返回类型改成ResponseEntity<ResponseBody>,明确告诉Spring要序列化的是你的自定义ResponseBody类:
@PostMapping("/search") public ResponseEntity<ResponseBody> getSearchResultViaAjax(@Valid @RequestBody SearchCriteria search, Errors errors) { ResponseBody result = new ResponseBody(); // 错误处理逻辑 if (errors.hasErrors()) { result.setCode("400"); result.setMessage("参数校验失败"); return ResponseEntity.badRequest().body(result); } // 正常业务逻辑 result.setCode("200"); result.setMessage("查询成功"); result.setData(/* 你的查询结果 */); return ResponseEntity.ok(result); }
2. 确保自定义ResponseBody类可被序列化
如果你的ResponseBody类没有提供属性的getter方法,或者属性是private且没有暴露访问方式,Jackson(Spring默认的JSON序列化库)没法读取属性值,也会导致序列化失败,最终触发这个异常。
解决办法:
- 如果你用Lombok,可以直接给
ResponseBody类加上@Data注解,自动生成getter、setter等方法:
@Data public class ResponseBody { private String code; private String message; private Object data; // 其他业务属性... }
- 不用Lombok的话,手动给每个需要序列化的属性编写public的getter方法:
public class ResponseBody { private String code; private String message; private Object data; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } }
3. 检查是否缺少JSON序列化依赖
Spring Boot的spring-boot-starter-web依赖默认包含了Jackson JSON库,但如果你的项目里不小心排除了这个依赖,或者手动移除了相关模块,也会导致没有可用的JSON转换器。
检查依赖:
- Maven项目(pom.xml)确保有以下依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
- Gradle项目(build.gradle)确保有:
implementation 'org.springframework.boot:spring-boot-starter-web'
按照上面这几步排查,基本就能解决这个问题了。我当时就是因为没指定ResponseEntity的泛型,踩了这个坑,改完泛型就正常了😉
内容的提问来源于stack exchange,提问作者smile95

