使用原生的 Feign 进行 HTTP 调用

本贴最后更新于 1448 天前,其中的信息可能已经东海扬尘

前言

在最开始学习 Spring Cloud 的时候,了解其中有个组件叫做 Feign : 可以通过既定规则在本地消费端存留一份服务提供者的接口,这样消费者便可以直接通过这个接口来进行服务消费。

Spring Cloud 是一个开源方案的整合体,其中的 Feign 组件整合的就是已有的一个开源组件 Feign

Feign 的中文含义是: 假装!

背景

最近有个项目需要调用第三方提供的 HTTP 接口,这个项目不是基于 Spring Cloud 的,所以 Spirng Cloud 已整合的 Feign 无法使用。

最开始考虑使用 Spring 自带的 HttpRestemplate 但是随着项目编码,发现这种方式使用其他不够方便,每次调用都要写一大堆代码:请求、处理响应、重试这些都需要自己处理,颇多不便。

正好想起了 Feign 这个开源组件,所以经过一番学习,重新引入了原生的 Feign 进行 HTTP 的调用,这里将学的东西做个简单记录。

服务提供者

先将服务提供者的 demo 代码附上

@RequestMapping("/stu")
@RestController
public class StuProvider {

    @GetMapping
    public StudentVo getBook(@RequestParam("id") String id) {
        System.out.println("id is " + id);
        return JMockData.mock(StudentVo.class);
    }

    @PostMapping
    public StudentVo postBook(@RequestBody StudentVo bookVo) {
        System.out.println(bookVo.toString());
        return bookVo;
    }

    @PostMapping("/map")
    public Map<String, StudentVo> postBook(@RequestBody List<StudentVo> bookVo) {
        System.out.println(bookVo.toString());
        return JMockData.mock(new TypeReference<Map<String, StudentVo>>() {
        });
    }

    @PostMapping("/param")
    public StudentVo postParam(@RequestParam("id") String id) {
        System.out.println("收到的id为:" + id);
        return JMockData.mock(StudentVo.class);
    }
}

Feign 接口

public interface StuApi {

    @Headers("Content-Type: application/json")
    @RequestLine("GET /stu?id={id}")
    StudentVo getBook(@Param("id") String id);

    @Headers({"Content-Type: application/json", "Accept: application/json"})
    @RequestLine("POST /stu")
    StudentVo postBook1(StudentVo bookVo);

    @Headers({"Content-Type: application/json", "Accept: application/json"})
    @RequestLine("POST /stu/map")
    Map<String, StudentVo> postBook2(List<StudentVo> bookVo);

    @Headers({"Content-Type: application/json", "Accept: application/json"})
    @RequestLine("POST /stu/param?id={id}")
    StudentVo postParam(@Param("id") String id);
}

@Headers

@Headers 这个注解需要指明请求的类型和响应类型。

  1. 如果只有响应的是 json,那么如第一个 api 所示
 @Headers("Content-Type: application/json")
  1. 如果请求和相应都是 json 格式,那么如后面 3 个所示:
 @Headers({"Content-Type: application/json", "Accept: application/json"})

实际测试后发现,只要是 @RestController 修饰的提供者,不管请求和响应类型,直接采用第二种都可以。

但是如果请求和响应都是 json,那么如果不些 @Headers 这个注解,肯定报错。比如后续的 2 3 4 这 3 个 API.

@RequestLine

通过 @RequestLine 来标明当前接口的类型。

比如如下 API 标明的就是 Get 请求

@RequestLine("GET /stu?id={id}")

Post 的类似

@RequestLine("POST /stu")

使用方法

构建了上述接口后,那么如何使用了,Feign 提供了基于 Builder 模式的构造

StuApi api = Feign.builder() //创建feign的构建者
	.encoder(new JacksonEncoder())  //JSON编码
	.decoder(new JacksonDecoder()) //JSON解码
	.options(new Request.Options(1000, 3500))  //设置超时
	.retryer(new Retryer.Default(5000, 5000, 3))  //设置重试
	.target(StuApi.class, "http://127.0.0.1:8080"); //设置代理的接口以及目标地址

然后可以通过 api.xxx 进行服务调用。

这里请不要忘记引入相关的引用,相关的 pom.xml

       <!--feign的客户端-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
            <version>9.7.0</version>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-core</artifactId>
            <version>9.7.0</version>
        </dependency>
        <!--因为使用的是jackson 序列化,所以引入此包-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-jackson</artifactId>
            <version>9.7.0</version>
        </dependency>
        <!--客户端使用的okhttp所以引入此包-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
            <version>9.7.0</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>3.10.0</version>
        </dependency>

其他相关的引用可以从此处查看:

http://mvnrepository.com/artifact/io.github.openfeign

总结

通过 Feign 的方式进行 HTTP 调用真心很方便,如果有涉及到需要调用第三方提供 HTTP 接口的时候,不妨考虑下 Feign

积土成山,风雨兴焉。积水成渊,蛟龙生焉。

1 操作
mulyzhou 在 2021-01-06 17:19:41 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...