背景
传统使用restTemplate来发送http请求,在springcloud大军下,基于完善自己的生态系统,springcloud开发自己的http组件openfeign,区别于restTemplate,openfeign基于接口注解编程。
使用时候,只需要定义自己的接口和标注对应openfeign注解即可发送http请求
使用方式
1 基于ip和端口、域名需添加属性url
2 只基于服务名,如ribbin,只需name即可
/**
* @author yingcly003
* @description: TODO
*/
@FeignClient(name = SERVICE_NAME , url = SERVICE_URL)
public interface TestFeignClient extends ITestApi {
}
/**
* @version 1.0
* @Author yingcly003
* @Date 2019/12/4 9:10
*/
@RestController
@RequestMapping("/test/test1/test2")
@Validated
public class TestController {
@Autowired
private TestFeignClient testFeignClient;
/**
* 品牌列表
*
* @return
*/
@GetMapping("/getAllBrand")
@ApiOperation("品牌列表")
public ReturnVo getAllBrand() throws Exception {
ReturnVo returnVo = testFeignClient.getAllBrand();
return returnVo;
}
}
配置
1 pom配置,需要openfeign基础包,okhttp包提供http连接池,基础包不含有改功能
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>10.2.3</version>
</dependency>
2 连接池配置和client配置
/**
*
* date 2021/12/14 18:13
*/
@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class FeignOkHttpConfig {
@Bean
@ConditionalOnMissingBean({Client.class})
public Client feignClient(okhttp3.OkHttpClient client) {
return new feign.okhttp.OkHttpClient(client);
}
@Bean
@ConditionalOnMissingBean({ConnectionPool.class}) //只允许只有一个ConnectionPool存在
public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties, OkHttpClientConnectionPoolFactory connectionPoolFactory) {
Integer maxTotalConnections = httpClientProperties.getMaxConnections();
Long timeToLive = httpClientProperties.getTimeToLive();
TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();
return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
}
@Bean
public OkHttpClient client(OkHttpClientFactory httpClientFactory, ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) {
Boolean followRedirects = httpClientProperties.isFollowRedirects();
Integer connectTimeout = httpClientProperties.getConnectionTimeout();
Boolean disableSslValidation = httpClientProperties.isDisableSslValidation();
return httpClientFactory.createBuilder(disableSslValidation)
.connectTimeout((long) connectTimeout, TimeUnit.MILLISECONDS)
.followRedirects(followRedirects)
.connectionPool(connectionPool)
//.addInterceptor(new OkHttpLogInterceptor()) // 自定义请求日志拦截器
.build();
}
}
3 其它Feign应用,给http增加头部参数,可实现RequestInterceptor
/**
*
* date 2021/12/21 11:51
*/
@Component
public class FeignInterceptor implements RequestInterceptor {
@Autowired
private HttpServletRequest request;
public void apply(RequestTemplate requestTemplate) {
// 获取request请求中的 params[lang] 信息放到requestTemplate params里
requestTemplate.query("lang", request.getHeader("lang"));
requestTemplate.query("access_token", request.getHeader("access_token"));
requestTemplate.query("client_ip", request.getHeader("client_ip"));
requestTemplate.header("lang", request.getHeader("lang"));
requestTemplate.header("access_token", request.getHeader("access_token"));
requestTemplate.header("client_ip", request.getHeader("client_ip"));
requestTemplate.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36");
// requestTemplate.query("lang", request.getHeader("lang"));
// requestTemplate.query("access_token", request.getHeader("access_token"));
}
}