feign入门教程

feign入门教程

1.介绍

feign简单来说是一个java http客户端,用来减少http API调用的复杂性。spring-Cloud-Netflix中就集成了feign客户端用来访问远程的http服务,不管是用来作为远程调用客户端,还是api接口测试都是非常方便的。
这里要讲的主要是OpenFeign。首先来看一下简单的操作例子


2.示例

interface GitHub {
  @RequestLine("GET /repos/{owner}/{repo}/contributors")
  List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}

static class Contributor {
  String login;
  int contributions;
}

public static void main(String... args) {
  GitHub github = Feign.builder()
                       .decoder(new GsonDecoder())
                       .target(GitHub.class, "https://api.github.com");

  // Fetch and print a list of the contributors to this library.
  List<Contributor> contributors = github.contributors("OpenFeign", "feign");
  for (Contributor contributor : contributors) {
    System.out.println(contributor.login + " (" + contributor.contributions + ")");
  }
}

@RequestLine定义了请求的http方法为GET,uri为/repos/{owner}/{repo}/contributors,{}中的参数会被@Param注解的参数所替换请求的url为https://api.github.com。feign访问此接口后会将返回的值转换成List类型。


3.客户端构建

feign客户端使用builder模式构建,可以设置logLevel、contract、client、logger、encoder、decoder等配置。其中比较重要的

  • encoder decoder 数据编解码器
  • client 配置发送http的客户端。
  • logLevel 配置日志等级为不输出日志、基础日志、输出http头、全部日志


3.1 encoder decoder

feign默认使用第三方工具实现了很多编解码器,如gson、jackson、Sax、JAXB
* 使用gson进行json序列化、反序化

GsonCodec codec = new GsonCodec();
GitHub github = Feign.builder()
                     .encoder(new GsonEncoder())
                     .decoder(new GsonDecoder())
                     .target(GitHub.class, "https://api.github.com");
  • 使用Jackson进行json序列化、反序化
GitHub github = Feign.builder()
                     .encoder(new JacksonEncoder())
                     .decoder(new JacksonDecoder())
                     .target(GitHub.class, "https://api.github.com");
  • 使用SAX进行xml反序化
api = Feign.builder()
           .decoder(SAXDecoder.builder()
           .registerContentHandler(UserIdHandler.class)
           .build())
           .target(Api.class, "https://apihost");
  • 使用JAXB访问xml api
api = Feign.builder()
           .encoder(new JAXBEncoder())
           .decoder(new JAXBDecoder())
           .target(Api.class, "https://apihost");


3.2 client

  • 使用OkHttp 客户端进行http访问
GitHub github = Feign.builder()
                     .client(new OkHttpClient())
                     .target(GitHub.class, "https://api.github.com");
  • 使用Ribbon 客户端进行http访问,可以使用ribbon的路由功能
MyService api = Feign.builder().client(RibbonClient.create()).target(MyService.class, "https://myAppProd");
  • 使用熔断器Hystrix客户端进行http访问
MyService api = HystrixFeign.builder().target(MyService.class, "https://myAppProd");

其他一些第三方实现就不多说了,自己可以去github查找


4.feign注解

  • @Param 需要发送的http参数,可以替换其他注解上的参数。如@RequestLine中uri参数 @Body中的请求体
  • @Headers 定义http请求的请求头 如定义content type @Headers(“Content-Type: application/x-www-form-urlencoded”)
  • @RequestLine 定义http的请求行,定义了访问和uri
  • @Body 定义请体的模板,使用@Param参数替换
  • @QueryMap 使用map作为请求的参数键值对
interface LoginClient {

  @RequestLine("POST /")
  @Headers("Content-Type: application/xml")
  @Body("<login \"user_name\"=\"{user_name}\" \"password\"=\"{password}\"/>")
  void xml(@Param("user_name") String user, @Param("password") String password);

  @RequestLine("POST /")
  @Headers("Content-Type: application/json")
  // json curly braces must be escaped!
  @Body("%7B\"user_name\": \"{user_name}\", \"password\": \"{password}\"%7D")
  void json(@Param("user_name") String user, @Param("password") String password);
}
...
client.xml("denominator", "secret"); // <login "user_name"="denominator" "password"="secret"/>
client.json("denominator", "secret"); // {"user_name": "denominator", "password": "secret"}

5.其他特性

5.1 接口继承

对于一些通用的接口,uri相同,只有域名不同,可以使用带泛型的接口的继承特性,

interface BaseAPI {
  @RequestLine("GET /health")
  String health();

  @RequestLine("GET /all")
  List<Entity> all();
}

interface CustomAPI extends BaseAPI {
  @RequestLine("GET /custom")
  String custom();
}
@Headers("Accept: application/json")
interface BaseApi<V> {

  @RequestLine("GET /api/{key}")
  V get(@Param("key") String key);

  @RequestLine("GET /api")
  List<V> list();

  @Headers("Content-Type: application/json")
  @RequestLine("PUT /api/{key}")
  void put(@Param("key") String key, V value);
}

interface FooApi extends BaseApi<Foo> { }

interface BarApi extends BaseApi<Bar> { }

5.2请求拦截器

实现RequestInterceptor接口在feign build的时候可以设置此拦截器,但是貌似并没有拦截功能,只能添加一些共用的代码
想要时间拦截可能需要抛出异常,中断请求。
如添加一些公用头部

static class ForwardedForInterceptor implements RequestInterceptor {
  @Override public void apply(RequestTemplate template) {
    template.header("X-Forwarded-For", "origin.host.com");
  }
}
...
Bank bank = Feign.builder()
                 .decoder(accountDecoder)
                 .requestInterceptor(new ForwardedForInterceptor())
                 .target(Bank.class, "https://api.examplebank.com");

5.3 参数toString

@Param注解的参数默认使用ToStringExpander转化为String
可以在@Param中定义expander,实现public String expand(Object value) 方法。

@RequestLine("GET /?since={date}") Result list(@Param(value = "date", expander = DateToMillis.class) Date date);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值