目录
JAVA 项目中如何实现接口调用?
1. 什么是Feign
2. Spring Cloud Alibaba快速整合OpenFeign
3. Spring Cloud Feign的自定义配置及使用
4.自定义拦截器
5.超时时间配置
JAVA 项目中如何实现接口调用?
1)Httpclient
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富
的支持 Http 协议的客户端编程工具包,并且它支持 HTTP 协议最新版本和建议。HttpClient
相比传统 JDK 自带的 URLConnection,提升了易用性和灵活性,使客户端发送 HTTP 请求变
得容易,提高了开发的效率。
2)Okhttp
一个处理网络请求的开源项目,是安卓端最火的轻量级框架,由 Square 公司贡献,用于替代
HttpUrlConnection 和 Apache HttpClient。OkHttp 拥有简洁的 API、高效的性能,并支持
多种协议(HTTP/2 和 SPDY)。
3)HttpURLConnection
HttpURLConnection 是
Java
的标准类,它继承自 URLConnection,可用于向指定网站发送
GET 请求、POST 请求。HttpURLConnection 使用比较复杂,不像 HttpClient 那样容易使
用。
4)
RestTemplate
WebClient
RestTemplate 是
Spring
提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便
捷访问远程 HTTP 服务的方法,能够大大提高客户端的编写效率。
上面介绍的是最常见的几种调用接口的方法,我们下面要介绍的方法比上面的更简单、方便,
它就是 Feign。
1. 什么是Feign
Feign是Netflix开发的声明式、模板化的HTTP客户端,其灵感来自Retrofit、JAXRS-2.0以及
WebSocket。Feign可帮助我们更加便捷、优雅地调用HTTP API。 Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
Spring Cloud
openfeign
对Feign进行了增强,使其支持Spring MVC注解,另外还整合了
Ribbon和Nacos,从而使得Feign的使用更加方便。
1.1 优势
Feign可以做到
使用 HTTP 请求远程服务时就像调用本地方法一样的体验
,开发者完全感知不
到这是远程方法,更感知不到这是个 HTTP 请求。它像 Dubbo 一样,consumer 直接调用接
口方法调用 provider,而不需要通过常规的 Http Client 构造请求再解析返回数据。它解决了
让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布
式环境开发。
2. Spring Cloud Alibaba快速整合OpenFeign
1)引入依赖
<!-- openfeig 远程调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2)编写调用接口+@FeignClient注解
package com.wang.openfeign;
import com.wang.config.FeignConfig;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author wang fei
* @description:
* 开启Feign, 根据不同的url,传入不同的参
* name 指定调用rest接口所在的服务名称
* path 指定调用rest接口所在的Controller指定的@RequestMapping映射路径
* 局部配置,让调用的微服务生效,在@FeignClient注解中指定使用的配置类,configuration = FeignConfig.class
**/
@FeignClient(name = "stock-nacos",path = "/stock")
public interface OrderFeignService {
//声明需要调用rest接口对应的方法
@RequestMapping("/reduct")
String reduct();
@RequestMapping("/reduct2")
String reduct2();
}
3)调用端在启动类上添加
@EnableFeignClients
注解
4)发起调用,像调用本地方式一样调用远程服务
package com.wang.controller;
import com.wang.openfeign.OrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @BelongsProject: SpringCloudAlibabaLearn
* @BelongsPackage: com.wang.controllter
* @Author: wang fei
* @CreateTime: 2023-01-16 16:48
* @Description: TODO
* @Version: 1.0
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
OrderFeignService orderFeignService;
@GetMapping("/pay")
public String pay(){
String msg = orderFeignService.reduct();
System.out.println("小王支付成功" + msg);
return msg;
}
}
3. Spring Cloud Feign的自定义配置及使用
Feign 提供了很多的扩展机制,让用户可以更加灵活的使用。
3.1 日志配置
有时候我们遇到 Bug,比如接口调用失败、参数没收到等问题,或者想看看调用性能,就需要
配置 Feign 的日志了,以此让 Feign 把请求信息输出来。
全局配置: 当使用@Configuration 会将配置作用所有的服务提供方 局部配置: 1. 通过配置类:如果只想针对某一个服务进行配置, 就不要加@Configuration 2. 通过配置文件
3.1全局配置: 当使用@Configuration 会将配置作用所有的服务提供方
1)定义一个配置类,指定日志级别
package com.wang.config;
import com.wang.intercptor.CustomFeignInterceptor;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @BelongsProject: SpringCloudAlibabaLearn
* @BelongsPackage: com.wang.config
* @Author: wang fei
* @CreateTime: 2023-01-20 15:26
* @Description: TODO
* @Version: 1.0
*/
/**
* 配置Feign的日志
* 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置
* @author 飞
*/
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置
通过源码可以看到日志等级有 4 种,分别是:
- NONE【性能最佳,适用于生产】:不记录任何日志(默认值)。
- BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及
执行时间。
- HEADERS:记录BASIC级别的基础上,记录请求和响应的header。
- FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body
和元数据。
3.2局部配置,让调用的微服务生效,在
@FeignClient 注解中指定使用的配置类
方式1:通过配置类:如果只想针对某一个服务进行配置, 就不要加@Configuration
1)配置类:
package com.wang.config;
import com.wang.intercptor.CustomFeignInterceptor;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @BelongsProject: SpringCloudAlibabaLearn
* @BelongsPackage: com.wang.config
* @Author: wang fei
* @CreateTime: 2023-01-20 15:26
* @Description: TODO
* @Version: 1.0
*/
/**
* 配置Feign的日志
* 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置
* @author 飞
*/
//@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
@Bean
public CustomFeignInterceptor feignAuthRequestInterceptor(){
return new CustomFeignInterceptor();
}
}
2)接口:
package com.wang.openfeign;
import com.wang.config.FeignConfig;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author wang fei
* @description:
* 开启Feign, 根据不同的url,传入不同的参
* name 指定调用rest接口所在的服务名称
* path 指定调用rest接口所在的Controller指定的@RequestMapping映射路径
* 局部配置,让调用的微服务生效,在@FeignClient注解中指定使用的配置类,configuration = FeignConfig.class
**/
@FeignClient(name = "stock-nacos",path = "/stock",configuration = FeignConfig.class)
public interface OrderFeignService {
//声明需要调用rest接口对应的方法
@RequestMapping("/reduct")
String reduct();
@RequestMapping("/reduct2")
String reduct2();
}
3)配置spring日志级别:
logging: level: com.wang.openfeign: debug #日志级别
补充:局部配置可以在yml中配置
对应属性配置类:
feign:
client:
config:
对应微服务名称
loggerLevel: FULL
方式2:通过配置文件(推荐)
feign:
client:
config:
stock-nacos:
loggerLevel: BASIC
效果截图:
4.自定义拦截器
我们openfeign实现RequestInterceptor接口定义自定义拦截器,在拦截器中完成相关业务。如下一个例子。
1)实现RequestInterceptor接口
package com.wang.intercptor;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import java.util.UUID;
/**
* @BelongsProject: SpringCloudAlibabaLearn
* @BelongsPackage: com.wang.intercptor
* @Author: wang fei
* @CreateTime: 2023-01-20 15:53
* @Description: TODO
* @Version: 1.0
*/
public class CustomFeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
/* TODO 自定义 feign 请求拦截器 业务逻辑 */
String access_token= UUID.randomUUID().toString();
requestTemplate.header("token",access_token);
System.out.println("请求拦截器feign自定义");
}
}
1)将自定义的拦截器配置
- 通过配置类配置
package com.wang.config;
import com.wang.intercptor.CustomFeignInterceptor;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @BelongsProject: SpringCloudAlibabaLearn
* @BelongsPackage: com.wang.config
* @Author: wang fei
* @CreateTime: 2023-01-20 15:26
* @Description: TODO
* @Version: 1.0
*/
/**
* 配置Feign的日志
* 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置
* @author 飞
*/
//@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
//自定义拦截器
@Bean
public CustomFeignInterceptor feignAuthRequestInterceptor(){
return new CustomFeignInterceptor();
}
}
- 通过配置文件配置
feign:
client:
config:
stock-nacos:
# loggerLevel: BASIC
# 连接超时时间,默认2s
connectTimeout: 5000
# 请求处理超时时间,默认5s
readTimeout: 10000
requestInterceptors[0]:
com.wang.interceptor.CustomFeignInterceptor #feign的拦截器自定义
5.超时时间配置
通过 Options 可以配置连接超时时间和读取超时时间,Options 的第一个参数是连接的超时
时间(ms),默认值是 2s;第二个是请求处理的超时时间(ms),默认值是 5s。
全局配置 :
@Configuration
public class FeignConfig {
@Bean
public Request.Options options() {
return new Request.Options(5000, 10000);
}
}
yml中配置 :
feign:
client:
config:
mall‐order: #对应微服务
# 连接超时时间,默认2s
connectTimeout: 5000
# 请求处理超时时间,默认5s
readTimeout: 10000