在微服务中使用Feign调用第三方的接口
概述:在微服务中我们一般使用FeignClient
作为服务内部组件的调用,如下:
@FeignClient(name = "xxx", fallbackFactory = xxxClientFallback.class)
public interface xxxClient {
//接口方法
}
因为name
一般都是一个常量,即注册到注册中心的服务,不太适合配置成一个url,那么使用FeignClient怎么调用第三方的接口呢?
接下来介绍一下一种使用Feign的工具类来调用的方式,避免在微服务项目中再使用原始http的方法来调用三方接口
1、引入坐标
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、工具类如下
import feign.Client;
import feign.Contract;
import feign.Feign;
import feign.Request.Options;
import feign.Retryer;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
import javax.net.ssl.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
@Component
@Import(FeignClientsConfiguration.class)
public class FeignUtil {
@Autowired
private Decoder decoder;
@Autowired
private Encoder encoder;
@Autowired
private Contract contract;
@Bean
@ConditionalOnMissingBean
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory) throws NoSuchAlgorithmException, KeyManagementException {
SSLContext ctx = SSLContext.getInstance("SSL");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
return new LoadBalancerFeignClient(new Client.Default(ctx.getSocketFactory(),
new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}),
cachingFactory, clientFactory);
}
public <T> T service(Class<T> apiType, String url) {
if (!url.startsWith("http")) {
url = "http://" + url;
}
return Feign.builder()
.options(new Options(30000, 30000))
.retryer(new Retryer.Default(5000, 5000, 3))
.decoder(decoder).encoder(encoder).contract(contract).target(apiType, url);
}
public <T> T service(Class<T> apiType, ServiceInstance instance) {
String url = "http://" + instance.getHost() + ":" + instance.getPort();
return Feign.builder()
.options(new Options(30000, 30000))
.retryer(new Retryer.Default(5000, 5000, 3))
.decoder(decoder).encoder(encoder).contract(contract).target(apiType, url);
}
}
3、在需要的地方注入使用
@Autowired
private FeignUtil feignUtil
在方法中调用feignUtil.service(),传入接口的Class对象,和要调用的接口url:
xxxService service = feignUtil.service(xxxService.class, url);
xxxService就是第三方接口方法:
public interface xxxService {
//获取票据
@PostMapping("/xxx/xx/getTickit")
public xxxResultDTO<String> getTicket(@RequestBody UserInfoDTO userInfoDTO);
}
已经获取到xxxService了,接下来直接调用getTicket接口即可:
xxxResultDTO<String> dto = service.getTicket(userInfoDTO);
就像getTicket在本系统内部调用一样,拿到三方接口提供的ticket !!
每天进步一点点~ peace
相关文章
暂无评论...