如何使用自定义Feign客户端解码JSON响应?

5
在我的应用程序中,我需要从服务器地址列表中确定哪些服务器是可用的。我找到的解决方案是对每个服务器调用Spring-Boot Actuator的健康检查端点。JSON响应如下:
{
    "status": "UP"
}

在该应用程序的其他部分中,我使用了使用@FeignClient注解定义的Spring-Cloud Feign客户端,其运作完美:

    @FeignClient(
            name = "tokenProxy",
            url = "${host}:${port}"
    )

很不幸,这种配置不能允许重复使用同一个客户端来调用不同地址上的同一端点。所以我必须定义自己的自定义客户端(如果有其他解决方案,请务必告诉我!):

    @GetMapping(
      value = "/servers"
    )
    public Server discover() {
      MyClient myClient = Feign.builder()
        .target(
          Target.EmptyTarget.create(
            MyClient.class
          )
        );

      return myClient.internalPing(URI.create("http://localhost:8090"));
    }

    interface MyClient {
        @RequestLine("GET /actuator/health")
        Server internalPing(URI baseUrl);
    }

    class Server {
        private final String status;

        @JsonCreator
        public Server(@JsonProperty("status") String status) {
            this.status = status;
        }

        public String getStatus() {
            return status;
        }
    }

当我调用端点/servers时,我收到了以下错误提示,这表明我的自定义Feign客户端没有使用适当的解码器进行配置:
feign.codec.DecodeException: class com.xxx.web.Server is not a type supported by this decoder.
    at feign.codec.StringDecoder.decode(StringDecoder.java:34) ~[feign-core-10.10.1.jar:na]
    at feign.codec.Decoder$Default.decode(Decoder.java:92) ~[feign-core-10.10.1.jar:na]
    at feign.AsyncResponseHandler.decode(AsyncResponseHandler.java:115) ~[feign-core-10.10.1.jar:na]
    at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:87) ~[feign-core-10.10.1.jar:na]
    at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138) ~[feign-core-10.10.1.jar:na]

我猜应该使用JacksonDecoder,但是在Spring-Cloud的依赖中Hoxton.SR5中找不到它:

      <dependencies>
    ...
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    ...
      </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Hoxton.SR5</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
  </dependencyManagement>

有人能帮我,提供更好的解决方案或者解释如何正确配置自定义 Feign 客户端吗?

谢谢。

2个回答

3
事实上,当使用spring-cloud依赖时,默认情况下不会加载包含Jackson解码器和编码器的库。为了解决这个问题,我只需要在我的pom.xml文件中添加以下内容:
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-jackson</artifactId>
</dependency>

1
我无法告诉你这个救了我多少次。我已经为此苦苦思索了几个小时 - 每个教程和在线文档都说使用Spring Boot应该一切都能顺利进行,但实际情况并非如此。 - undefined

2
另一种方法是使用@Import(FeignClientsConfiguration.class)注释该类,这是Spring Cloud Netflix提供的默认配置。然后在创建Feign客户端时,注入编码器和解码器变得很容易:
    @Import(FeignClientsConfiguration.class)
    @Configuration
    public class MyConfiguration {
    (...)
    Myclient myClient (Decoder feignDecoder, Encoder feignEncoder) {
    return Feign.builder()
        .decoder( feignDecoder )
        .encoder( feignEncoder )
        .target(
          Target.EmptyTarget.create(
            MyClient.class
          )
        );
    }

在配置类中有两种不同的编码器(分页或非分页),因此请注意清楚地标识您想要哪种,可以通过名称或限定符来标识。

这个答案真的救了我,我已经忙于解码问题将近一个星期了。谢谢你! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接