Spring RestTemplate 'no suitable HttpMessageConverter found'错误排查思路
嘿,我来帮你梳理下这个问题的切入点和排查逻辑,先把你的问题背景整理清楚:
问题背景
我开发了一个简易Spring Boot应用,尝试调用Rest服务,核心代码如下:
ConsumingRestApplication类
@SpringBootApplication public class ConsumingRestApplication { private static final Logger log = LoggerFactory.getLogger(ConsumingRestApplication.class); public static void main(String[] args) { SpringApplication.run(ConsumingRestApplication.class, args); } @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.build(); } @Bean public CommandLineRunner run(RestTemplate restTemplate) throws Exception { return args -> { try { restTemplate.getForObject("https://gturnquist-quoters.cfapps.io/api/random", Quote.class); } catch (RestClientException e) { e.printStackTrace(); } }; } }
Quote类
@JsonIgnoreProperties(ignoreUnknown = true) public class Quote { private String type; private Value value; public Quote() { } public String getType() { return type; } public void setType(String type) { this.type = type; } public Value getValue() { return value; } public void setValue(Value value) { this.value = value; } @Override public String toString() { return "Quote{" + "type='" + type + '\'' + ", value=" + value + '}'; } }
运行时抛出核心错误:
org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.example.consumingrest.Quote] and content type [application/json;charset=UTF-8]
从异常栈里能看到关键警告:
2020-10-19 12:39:07.786 WARN 8328 --- [ restartedMain] .c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class com.example.consumingrest.Quote]]: com.fasterxml.jackson.databind.JsonMappingException: Cannot deserialize Class org.springframework.beans.factory.annotation.Value (of type annotation) as a Bean
问题切入点:抓准异常里的关键线索
别被顶层的UnknownContentTypeException迷惑了,往下看异常栈里的警告信息——Cannot deserialize Class org.springframework.beans.factory.annotation.Value (of type annotation) as a Bean,这才是破局点!
这句话直接说明:Jackson在尝试把返回的JSON反序列化成Quote对象时,把Quote类里的value字段错误识别成了Spring的@Value注解类,而不是你应该定义的自定义Value实体类。
说白了,要么你没写配套的Value实体类,要么就是Quote类里Value的包导入错了(不小心导入了Spring的注解,而非自己的实体)。
排查逻辑:一步步验证
我给你整理一套递进的排查步骤,按顺序来就能找到问题:
先检查实体类的完整性和导入
- 首先确认你有没有创建和
Quote配套的Value实体类?这个类需要对应接口返回的JSON里value节点的字段,比如接口返回的JSON结构是:
那你的{ "type": "success", "value": { "id": 1, "quote": "Spring Boot makes developing web applications ridiculously easy." } }Value类应该是这样的:@JsonIgnoreProperties(ignoreUnknown = true) public class Value { private Long id; private String quote; public Value() {} // 必须有无参构造,Jackson需要这个来实例化对象 // 别忘了getter和setter public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getQuote() { return quote; } public void setQuote(String quote) { this.quote = quote; } @Override public String toString() { return "Value{" + "id=" + id + ", quote='" + quote + '\'' + '}'; } } - 然后检查
Quote类里的Value导入:确保是你自己写的com.example.consumingrest.Value,而不是org.springframework.beans.factory.annotation.Value(这个是Spring的注解,不是实体类!)
- 首先确认你有没有创建和
验证Jackson依赖是否正常
Spring Boot的spring-boot-starter-web依赖默认已经包含了Jackson的JSON处理包,所以先检查你的pom.xml(Maven)或build.gradle(Gradle)里有没有引入这个starter:- Maven:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> - Gradle:
implementation 'org.springframework.boot:spring-boot-starter-web'
如果是单独引入Jackson,要确保版本和Spring Boot版本兼容,避免出现依赖冲突。
- Maven:
确认接口返回格式和实体类匹配
用curl或者Postman调用https://gturnquist-quoters.cfapps.io/api/random,看看返回的JSON结构是不是和你的实体类字段对应,比如有没有拼写错误(比如接口返回的是quote,你实体类写的是quota),或者字段类型不匹配(比如接口返回的id是数字,你实体类用了String)。调试RestTemplate的消息转换器
如果前面都没问题,可以在代码里打印RestTemplate注册的消息转换器,确认MappingJackson2HttpMessageConverter存在(这个是处理JSON的核心转换器):restTemplate.getMessageConverters().forEach(converter -> { log.info("已注册的消息转换器:{}", converter.getClass().getName()); });如果发现这个转换器没注册,可以手动添加:
@Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.messageConverters(new MappingJackson2HttpMessageConverter()).build(); }
内容的提问来源于stack exchange,提问作者vico

