Feign:增强型的Java HTTP客户端

https://github.com/OpenFeign/feign

Feign使得 Java HTTP 客户端编写更方便。

Feign最初是为了降低统一绑定Denominator到HTTP API的复杂度,不区分是否支持Restful。

Feign旨在通过最少的资源和代码来实现和HTTP API的连接。

通过可定制的解码器和错误处理,可以编写任意的HTTP API。

Feign可以结合hystrix一起使用,hystrix通过服务隔离、熔断(也可以称为断路)、降级等手段控制依赖服务的延迟与失败。

主要特点:

  • 定制化
  • 提供多个接口
  • 支持JSON格式的编码和解码
  • 支持XML格式的编码和解码

代码示例:

import feign.*;
import feign.codec.ErrorDecoder;
import feign.codec.Decoder;
import feign.gson.GsonDecoder;
 
import java.io.IOException;
import java.util.List;
 
public class GitHubExample {
 
    interface GitHub {  // 1
        @RequestLine("GET /repos/{owner}/{repo}/contributors")
        List contributors(@Param("owner") String owner, @Param("repo") String repo);
    }
 
 
    public static void main(String... args) {
        Decoder decoder = new GsonDecoder();  // 2
        GitHub github = Feign.builder()
                .decoder(decoder) // 3
                .errorDecoder(new GitHubErrorDecoder(decoder))  // 4
                .logger(new Logger.ErrorLogger())  // 5
                .logLevel(Logger.Level.BASIC)  // 5
                .target(GitHub.class, "https://api.github.com");  // 6
 
        System.out.println("Let's fetch and print a list of the contributors to this library.");
        List contributors = github.contributors("netflix", "feign");  // 7
        for (Contributor contributor : contributors) {
            System.out.println(contributor.login + " (" + contributor.contributions + ")");
        }
 
        System.out.println("Now, let's cause an error.");
        try {
            github.contributors("netflix", "some-unknown-project");  // 8
        } catch (GitHubClientError e) {
            System.out.println(e.getMessage());
        }
    }
 
    static class Contributor {
        String login;
        int contributions;
    }
 
    static class GitHubClientError extends RuntimeException {  // 4
        private String message; // parsed from json
 
        @Override
        public String getMessage() {
            return message;
        }
    }
 
    static class GitHubErrorDecoder implements ErrorDecoder {   // 4
 
        final Decoder decoder;
        final ErrorDecoder defaultDecoder = new ErrorDecoder.Default();
 
        GitHubErrorDecoder(Decoder decoder) {
            this.decoder = decoder;
        }
 
        @Override
        public Exception decode(String methodKey, Response response) {
            try {
                return (Exception) decoder.decode(response, GitHubClientError.class);
            } catch (IOException fallbackToDefault) {
                return defaultDecoder.decode(methodKey, response);
            }
        }
    }
}


1. 首先定义接口GitHub,使用注解RequestLine 表明contributors()方法为一个get请求,请求相对为/repos/{owner}/{repo}/contributors;
2. Decoder decoder = new GsonDecoder(); 创建一个GsonDecoder解码器,表明通过Gson解析返回数据;
3. decoder()方法设置解码器 ;
4. errorDecoder()指定发生异常时的解码器,需要实现ErrorDecoder接口,覆写decode方法,通过指定的Decoder解析错误信息,这里还是使用GsonDecoder ;
5. logger()方法配置日志;
6. target() 方法指定访问url以及返回的类型;
7. 通过创建的github对象调用contributors获取结果;
8. 模拟异常情况。

可定制:

Feign在一些方面可以定制。举个简单的例子,可以使用Feign.builder()来构建一个API 接口,包含自定义的内容。

interface Bank {
  @RequestLine("POST /account/{id}")
  Account getAccountInfo(@Param("id") String id);
}
...
Bank bank = Feign.builder()
            .decoder(new AccountDecoder())
            .target(Bank.class, "https://api.examplebank.com");

支持多种接口: 

Feign可以提供多种API 接口。这些都被定义为Target(默认为 HardCodeTarget)。它允许动态扩展,并且被修饰过的请求会被优先执行。

例如,以下部分可以修饰来自当前身份验证服务的URL和AUTH的每一个请求。

Feign feign = Feign.builder().build();
CloudDNS cloudDNS = feign.target(new CloudIdentityTarget(user, apiKey));

你可能感兴趣的:(Java)