原生Feign入门示例

Feign简介

Feign是一种负载均衡的HTTP客户端, 使用Feign调用API就像调用本地方法一样。
GitHub地址:https://github.com/OpenFeign/feign

Feign使用

1、 引入依赖

至少需要引入核心依赖和一种json或者xml的一种解析工具

Feign将方法签名中方法参数对象序列化为请求参数放到HTTP请求中的过程,是由编码器(Encoder)完成的。同理,将HTTP响应数据反序列化为java对象是由解码器(Decoder)完成的。

json解析工具支持:feign-gson、feign-jackson
xml解析工具支持:feign-sax、feign-jaxb、feign-jaxrs

<dependency>
  <groupId>com.netflix.feign</groupId>
  <artifactId>feign-core</artifactId>
  <version>8.18.0</version>
  <scope>runtime</scope>
</dependency>

<dependency>
  <groupId>com.netflix.feign</groupId>
  <artifactId>feign-jackson</artifactId>
  <version>8.18.0</version>
</dependency>

<dependency>
    <groupId>com.netflix.feign</groupId>
    <artifactId>feign-slf4j</artifactId>
    <version>8.18.0</version>
</dependency>

2、 定义Api的接口

定义一个实体,用于将api的结果封装到对象中

public class Contributor {
    private String login;
    private int contributions;

    // Getter&Setter
}

定义一个Api接口,接口中声明每个api对应的请求方式、地址、参数、请求头等信息

import feign.*;

import java.util.List;
import java.util.Map;

// 给BaseApi中的所有方法设置Accept请求头
@Headers("Accept: application/json")
public interface ApiService {
    // 查看某个用户下的某个仓库的所有贡献者
    @RequestLine("GET /repos/{owner}/{repo}/contributors")
    @Headers("Content-Type: application/json")  // 单独给put方法设置Content-Type请求头
    public List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);

    @RequestLine("GET /search/issues")
    public Map<String, Object> searchIssues(@QueryMap Map<String, Object> queryMap);
}

定义一个拦截器,用于拦截所有的请求

import feign.RequestInterceptor;
import feign.RequestTemplate;

public class ApiRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {
        System.out.println("拦截请求:" + requestTemplate.method() + " " + requestTemplate.url());
    }
}

3、FeignTest

import feign.Feign;
import feign.Request;
import feign.Retryer;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import feign.okhttp.OkHttpClient;
import feign.slf4j.Slf4jLogger;
import org.junit.Assert;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FeignTest extends SpringTestCase {

    @Test
    public void testJsonApi(){
        // 编码器、解码器: 用于解析响应的内容
        Encoder encoder = new JacksonEncoder();
        Decoder decoder = new JacksonDecoder();

        ApiService apiService = Feign.builder()
                .logger(new Slf4jLogger())
                .encoder(encoder)
                .decoder(decoder)
                .requestInterceptor(new ApiRequestInterceptor())
                .options(new Request.Options(1000, 3500))   // 设置连接超时时长及响应超时时长
                .retryer(new Retryer.Default(5000, 5000, 3))    // 重试策略
                .target(ApiService.class, "https://api.github.com");    // 绑定接口和地址

        // 其实就是使用Get方法调用https://api.github.com/repos/OpenFeign/feign/contributors
        // 可以通过https://api.github.com/ 查看github对外的接口
        List<Contributor> contributors = apiService.contributors("OpenFeign", "feign");
        Assert.assertNotNull(contributors);
    }

    // 动态查询参数 queryMap
    @Test
    public void testDynamicQueryParameters(){
        ApiService apiService = Feign.builder()
                .logger(new Slf4jLogger())
                .encoder(new JacksonEncoder())
                .decoder(new JacksonDecoder())
                .requestInterceptor(new ApiRequestInterceptor())
                .target(ApiService.class, "https://api.github.com");
        Map<String, Object> queryMap = new HashMap<String, Object>();
        queryMap.put("q", "FeignException");
        queryMap.put("page", 1);
        queryMap.put("per_page", 10);

        Map<String, Object> responseMap = apiService.searchIssues(queryMap);
        System.out.println(responseMap.size());
    }

    @Test
    public void testOkHttp(){
        ApiService apiService = Feign.builder().decoder(new JacksonDecoder()).client(new OkHttpClient()).target(ApiService.class, "https://api.github.com");
        List<Contributor> contributors = apiService.contributors("OpenFeign", "feign");
        Assert.assertNotNull(contributors);
    }
}

Feign在默认情况下使用的是JDK原生的URLConnection发送HTTP请求,没有连接池,但是对每个地址会保持一个长连接,即利用HTTP的persistence connection 。我们可以用Apache的HTTP Client或者使用OkHttpClient替换Feign原始的http client, 从而获取连接池、超时时间等与性能息息相关的控制能力

OkHttpClient 使用 OkHttp 来发送 Feign 的请求,OkHttp 支持 SPDY (SPDY是Google开发的基于TCP的传输层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验),
并有更好的控制http请求。

feign与OkHttp集成

<dependency>
    <groupId>com.netflix.feign</groupId>
    <artifactId>feign-okhttp</artifactId>
    <version>8.18.0</version>
</dependency> 
GitHubService gitHubService = Feign.builder().decoder(new JacksonDecoder()).client(new OkHttpClient()).target(GitHubService.class, "https://api.github.com");

feign与apache httpclient集成

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.5</version>
</dependency>

<dependency>
  <groupId>com.netflix.feign</groupId>
  <artifactId>feign-httpclient</artifactId>
  <version>8.18.0</version>
</dependency>
@Test
public void testApacheHttpClient(){
    ApiService apiService = Feign.builder().decoder(new JacksonDecoder()).client(new ApacheHttpClient()).target(ApiService.class, "https://api.github.com");
    List<Contributor> contributors = apiService.contributors("OpenFeign", "feign");
    Assert.assertNotNull(contributors);
}

Feign还可以与Ribbon、Hystrix集成

RibbonClient 重写了 Feign 客户端的对URL的处理,其添加了 智能路由以及一些其他由Ribbon提供的弹性功能。
HystrixFeign 配置了 Hystrix 提供的熔断机制。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风流 少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值