官方使用文档: 链接 https://github.com/OpenFeign/feign
关于Feign的相关版本问题,参见 此链接
feign提供的注解:链接
@RequestLine:声明请求方法和请求地址,可以允许有参数
@Param:参数
@QueryMap:动态参数
@Body:声明请求体模板,模板中可以带有参数
@Headers:支持给请求的api或者请求的客户端设置请求头
@HeaderMap:动态请求头
示例
maven依赖
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>10.5.1</version>
</dependency>
构建FeignClient接口实现
/**
* 统一的 feign 接口实现类获取逻辑
*/
public static final <T> T getFeignClient(Class<T> clazz, String url) {
T feignClient = Feign.builder()
.logger(new FeignInfoLogger()) // 自定义日志类,继承 feign.Logger
.logLevel(Logger.Level.BASIC)// 日志级别
.client(new Client.Default(null, null))// 默认 http
.retryer(new Retryer.Default(5000, 5000, 1))//5s超时,仅1次重试
.target(clazz, url);
return feignClient;
}
动态url
我们知道,构建Feign的接口实现时,需要传递一个 url 参数Feign.builder().target(IFeignClientAPI.class, url);
,这样这个实现类已经和这个url绑定,当遇到需要向多个节点(不同url)发送相同的请求时,需要构建多个实现。很不方便。
实际上,Feign已经提供了一种机制,可以动态的替换该url。 具体操作是在方法增加一个 URI 类型的参数,方法执行时,该 URI对象会动态替换原来的 url 而不需要重新构建新的实现类,示例如下:
interface IFeignClientAPI {
@RequestLine("GET /query")
String query();
@RequestLine("GET /query")
String query(URI uri); // 增加 URI 参数!!!
}
// 调用方式
IFeignClientAPI feignClient = Feign.builder().target(IFeignClientAPI.class, "http://10.1.2.3:8080/");
feignClient.query(); //实际请求地址:http://10.1.2.3:8080/query
feignClient.query(new URI("http://127.0.0.1:80")); //实际请求地址:http://127.0.0.1:80/query,实现了同个 feignclient 可以访问多个url
//注意:此处URI必须以 http 开头!如果仅写 127.0.0.1,那么实际请求地址会变成http://10.1.2.3:8080/127.0.0.1/query/a
带参数的请求 @Param
// 客户端代码
@RequestLine("GET /feign/{id}?param1={param1}¶m2={param2}")
String get(@Param("id") String id, @Param("param1") String param1, @Param("param2") String param2);
// 服务端代码
@RequestMapping("/{id}")
public String get(@PathVariable("id") String id, @RequestParam("param1") String param1, @RequestParam("param2")String param2){
String str = id + "," + param1 + "," + param2;
System.out.println(str);
return str;
}
带动态参数的请求 @QueryMap
// 客户端代码
@RequestLine("GET /feign/{id}")
String get(@Param("id") String id, @QueryMap Map queryMap);
// 服务端代码
@RequestMapping("/{id}")
public String get(@PathVariable("id") String id, @RequestParam("param1") String param1, @RequestParam("param2")String param2){
String str = id + "," + param1 + "," + param2;
System.out.println(str);
return str;
}
下载文件的请求
使用 feign.Response 作为方法返回值
// 客户端代码
@RequestLine("GET /download")
feign.Response download();
// 客户端调用
feign.Response response = this.download();
try(OutputStream outputStream = new FileOutputStream("download-test-file.txt");
InputStream inputStream = response.body().asInputStream();) {
IOUtils.copy(inputStream, outputStream);
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
}
// 服务端代码
@RequestMapping("download")
public void download(HttpServletResponse response){
String filename = "test-file.txt";
try {
InputStream inputStream = new FileInputStream(filename);
response.reset();
response.setHeader("Content-disposition", "attachment; filename=\"" + filename+ "\"");
// response.addHeader("Content-Length", "" + bytes.length);
response.setContentType("application/octet-stream;charset=UTF-8");
OutputStream outputStream = response.getOutputStream();
IOUtils.copy(inputStream, outputStream);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
带请求体的请求 @Body
refer:
https://github.com/OpenFeign/feign
https://blog.csdn.net/u010862794/article/details/73649616
end