在微服务中使用Feign调用第三方的接口

在微服务中使用Feign调用第三方的接口

概述:在微服务中我们一般使用FeignClient作为服务内部组件的调用,如下:

@FeignClient(name = "xxx", fallbackFactory = xxxClientFallback.class)
public interface xxxClient {
	//接口方法
}

因为name一般都是一个常量,即注册到注册中心的服务,不太适合配置成一个url,那么使用FeignClient怎么调用第三方的接口呢?
接下来介绍一下一种使用Feign的工具类来调用的方式,避免在微服务项目中再使用原始http的方法来调用三方接口

1、引入坐标

<dependency>
	<groupId>org.springframework.cloudgroupId>
	<artifactId>spring-cloud-starter-openfeignartifactId>
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

你可能感兴趣的:(Java学习,微服务,spring,cloud,java)