我正在尝试让Spring Cloud Netflix Feign客户端通过HTTP获取一些JSON并将其转换为对象。我不断收到此错误:
org.springframework.web.client.RestClientException:无法提取响应:找不到适合响应类型 [class io.urig.checkout.Book] 和内容类型 [application/json;charset=UTF-8] 的 HttpMessageConverter。
下面是从远程服务返回的 JSON 位:
{
"id": 1,
"title": "Moby Dick",
"author": "Herman Melville"
}
这是我尝试反序列化的相应类:
package io.urig.checkout;
public class Book {
private long id;
private String title;
private String author;
public Book() {}
public Book(long id, String title, String author) {
super();
this.id = id;
this.title = title;
this.author = author;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
这是我的假装客户端:
package io.urig.checkout;
import java.util.Optional;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import io.urig.checkout.Book;
@FeignClient(name="inventory", url="http://localhost:8080/")
public interface InventoryClient {
@RequestMapping(method = RequestMethod.GET, value = "books/{bookId}")
public Optional<Book> getBookById(@PathVariable(value="bookId") Long bookId);
}
我需要做什么才能让它工作?
Feign,但是当我遇到"找不到合适的HttpMessageConverter......"过去的错误,这是因为内容类型尚未注册。也许您需要将其添加到请求映射中:
consumes = "application/json"
我所能建议的就是尝试确认Feign配置是否已将MappingJackson2HttpMessageConverter注册为Book的转换器。不确定这是否应该开箱即用地使用 Feign,或者您是否必须手动完成。我在Feign的GitHub上看到一个例子,它有:
GitHub github = Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.target(GitHub.class, "https://api.github.com");
您是否使用 Feign.builder(( 或一些等效的配置文件创建了配置?
确保类路径上至少有一个 JSON 库。 Feign 同时支持 GSON
和 Jackson
,如果在您的类路径中找到实例,Spring Cloud OpenFeign
将自动配置具有适当MessageConverter
的SpringEncoder
和SpringDecoder
实例。 确保您的pom.xml
或build.gradle
中至少有以下一项
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
或
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
一旦找到它们,Spring 将注册适当的MessageConverter
我认为您的问题是响应类型。尝试将其从可选转换为预订。如果要返回可选,则应提供自定义转换器。
对不起,回答太晚了。
有同样的问题。
只需向@RequestMapping添加两个参数 -
consumes = "application/json", produces = "application/json"
在您的代码中,这将如下所示 -
package io.urig.checkout;
import java.util.Optional;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import io.urig.checkout.Book;
@FeignClient(name="inventory", url="http://localhost:8080/")
public interface InventoryClient {
@RequestMapping(method = RequestMethod.GET, value = "books/{bookId}", consumes = "application/json", produces = "application/json")
public Optional<Book> getBookById(@PathVariable(value="bookId") Long bookId);
}
感谢所有试图提供帮助的人!
事实证明,我的问题是一个有缺陷的Maven依赖项,可能在下载或安装过程中损坏。完全删除了我机器上的.m2/repository
文件夹,然后更新了项目的Maven依赖项,问题现在消失了。
我来晚了,但我想再补充一点。就我而言,当您将返回类型指定为特定模型/实体类并且找不到该实体时,我观察到 Spring Feign 客户端返回此异常。
您应该检查正在调用的另一个服务的响应,并查看它在找不到实体或引发异常时返回的响应。
因此,如果未找到实体或引发任何异常,并且该响应与您在返回类型中指定的内容不匹配,则会在客户端服务中引发此异常。
我从FeignClient
中的@PostMapping
中得到了同样的错误,作为PostMapping Annotation的path
参数中错误的副作用。 它与我的FeignClient引用属性文件有关,因为它引用了path
参数的值:
@PostMapping(path = "{my.property-name-from-properties-file}")
路径的属性引用未正确解析,一旦我解决了这个问题,它就解决了此处有问题feign.codec.DecodeException
。 (并且首先通过为路径值提供硬编码字符串而不是属性值引用来进行故障排除(。
就我而言,我忘记了需要前缀的$
字符:
@PostMapping(path = "${my.property-name-from-properties-file}")