3

我正在尝试让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;
    }
}

这是我的 Feign 客户:

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);

}

我需要做什么才能使其正常工作?

4

5 回答 5

4

我不知道Feign,但是当我过去出现“没有找到合适的HttpMessageConverter ...”错误时,那是因为内容类型尚未注册。也许您需要将其添加到 RequestMapping:

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() 或一些等效的配置文件创建了配置?

于 2018-03-09T14:52:32.183 回答
1

我认为您的问题是响应类型。尝试将其从 Optional 转换为 Book。如果要返回 Optional,则应提供自定义转换器。

于 2018-03-09T18:10:20.003 回答
1

您需要确保您的类路径中至少有一个 JSON 库。Feign 支持GSONandJackson并且如果在你的类路径中找到它们,Spring Cloud OpenFeign它将使用适当的自动配置SpringEncoderSpringDecoder实例。MessageConverter确保您的pom.xmlbuild.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

于 2018-03-09T18:15:19.700 回答
1

抱歉,回答太晚了。

有同样的问题。

只需将两个参数添加到您的 @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);

}
于 2021-09-27T15:01:42.790 回答
0

感谢所有试图提供帮助的人!

事实证明,我的问题是有缺陷的 Maven 依赖项,可能在下载或安装过程中损坏。完全删除了.m2/repository我机器上的文件夹,然后更新了项目的 Maven 依赖项,问题现在消失了。

于 2018-03-10T08:33:35.037 回答