英文:
Solving "no suitable HttpMessageConverter found" error
问题
以下是您提供的代码的翻译部分:
我有一个简单的应用程序,试图消费Rest服务:
@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();
}
};
}
}
@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: 无法提取响应:找不到适合的HttpMessageConverter,用于响应类型 [class com.example.consumingrest.Quote] 和内容类型 [application/json;charset=UTF-8]
完整的异常跟踪:
2020-10-19 12:39:04.984 INFO 8328 --- [ restartedMain] c.e.c.ConsumingRestApplication : 正在启动 ConsumingRestApplication,进程ID 8328(位于 C:\gdrive\java_test\consumingrest\build\classes\java\main,由 g 在 C:\gdrive\java_test\consumingrest 中启动)
2020-10-19 12:39:04.987 INFO 8328 --- [ restartedMain] c.e.c.ConsumingRestApplication : 未设置活动配置文件,回退到默认配置文件:default
2020-10-19 12:39:05.070 INFO 8328 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools 属性默认值处于活动状态!将“spring.devtools.add-properties”设置为“false”以禁用
2020-10-19 12:39:05.070 INFO 8328 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : 要获取更多与 Web 相关的日志记录,请考虑将“logging.level.web”属性设置为“DEBUG”
2020-10-19 12:39:06.843 INFO 8328 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : 使用端口号初始化了 Tomcat:8080(http)
...(以下省略)
org.springframework.web.client.UnknownContentTypeException: 无法提取响应:找不到适合的HttpMessageConverter,用于响应类型 [class com.example.consumingrest.Quote] 和内容类型 [application/json;charset=UTF-8]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:126)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:741)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:674)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:315)
at com.example.consumingrest.ConsumingRestApplication.lambda$run$0(ConsumingRestApplication.java:37)
...(以下省略)
解决此问题的起始点是什么?我应该采取什么逻辑来找到问题?
英文:
I have simple application that is trying consume Rest service:
@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 class:
@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 +
'}';
}
}
Got error :
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]
Whole exception trace:
2020-10-19 12:39:04.984 INFO 8328 --- [ restartedMain] c.e.c.ConsumingRestApplication : Starting ConsumingRestApplication on GM with PID 8328 (C:\gdrive\java_test\consumingrest\build\classes\java\main started by g in C:\gdrive\java_test\consumingrest)
2020-10-19 12:39:04.987 INFO 8328 --- [ restartedMain] c.e.c.ConsumingRestApplication : No active profile set, falling back to default profiles: default
2020-10-19 12:39:05.070 INFO 8328 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2020-10-19 12:39:05.070 INFO 8328 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2020-10-19 12:39:06.843 INFO 8328 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-10-19 12:39:06.856 INFO 8328 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-10-19 12:39:06.857 INFO 8328 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.38]
2020-10-19 12:39:06.957 INFO 8328 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-10-19 12:39:06.957 INFO 8328 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1887 ms
2020-10-19 12:39:07.204 INFO 8328 --- [ restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-10-19 12:39:07.395 INFO 8328 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2020-10-19 12:39:07.603 INFO 8328 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-10-19 12:39:07.617 INFO 8328 --- [ restartedMain] c.e.c.ConsumingRestApplication : Started ConsumingRestApplication in 3.076 seconds (JVM running for 3.545)
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
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
2020-10-19 12:39:08.541 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
2020-10-19 12:39:08.542 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
2020-10-19 12:39:08.544 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
2020-10-19 12:39:08.545 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
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]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:126)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:741)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:674)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:315)
at com.example.consumingrest.ConsumingRestApplication.lambda$run$0(ConsumingRestApplication.java:37)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:779)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at com.example.consumingrest.ConsumingRestApplication.main(ConsumingRestApplication.java:21)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
What is starting point o solving this problem? What logic I should go to find problem?
答案1
得分: 1
我认为您可能遗漏了 Value
对象,或者可能导入错误。除此之外,如果字段是私有的,在直接在响应中返回该对象时,您需要为这些字段添加 getter 方法。以下是我是如何做的:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@RestController
public static class Test {
@Autowired
private RestTemplate restTemplate;
@GetMapping
public Quote test() {
return restTemplate.getForObject("https://gturnquist-quoters.cfapps.io/api/random", Quote.class);
}
}
public static class Quote {
private String type;
private Value value;
public String getType() {
return type;
}
public Value getValue() {
return value;
}
}
public static class Value {
private Long id;
private String quote;
public Long getId() {
return id;
}
public String getQuote() {
return quote;
}
}
}
英文:
I believe you are missing Value
object or must be a wrong import. Along with that you need to add getter methods for the field if they are private, when you are returning that object directly in the response, here is how i have done it:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@RestController
public static class Test {
@Autowired
private RestTemplate restTemplate;
@GetMapping
public Quote test() {
return restTemplate.getForObject("https://gturnquist-quoters.cfapps.io/api/random", Quote.class);
}
}
public static class Quote {
private String type;
private Value value;
public String getType() {
return type;
}
public Value getValue() {
return value;
}
}
public static class Value {
private Long id;
private String quote;
public Long getId() {
return id;
}
public String getQuote() {
return quote;
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论