在Spring-Cloud-Feign上配置代理路由规划器

时间:2018-04-23 13:50:37

标签: rest configure http-proxy spring-cloud-feign feign

在Feign上配置代理路由规划器

我需要知道如何使用spring boot REST客户端在代理服务器后面发出请求。我可以使用apache commons为REST请求执行此配置,如下所示:

执行POST的方法:

Map <String, Object> map = new TreeMap <String, Object> ();

DynamicProxyRoutePlanner routePlanner = getProxy (param);

CloseableHttpClient closeableHttpClient = HttpClients.custom (). SetRoutePlanner (routePlanner) .build ();

GetProxy方法:

private DynamicProxyRoutePlanner getProxy (Map <Integer, Object> param) {
        HttpHost proxy = new HttpHost ((String) param.get (PROXY), (Integer) param.get (PROXY_PORT));

        DynamicProxyRoutePlanner routePlanner = new DynamicProxyRoutePlanner (proxy);
        return routePlanner;
}

DynamicProxyRoutePlanner类:

public class DynamicProxyRoutePlanner implements HttpRoutePlanner {

    private DefaultProxyRoutePlanner defaultProxyRoutePlanner = null;

    public DynamicProxyRoutePlanner (HttpHost host) {
        defaultProxyRoutePlanner = new DefaultProxyRoutePlanner (host);
    }

    public void setProxy (HttpHost host) {
        defaultProxyRoutePlanner = new DefaultProxyRoutePlanner (host);
    }

    public HttpRoute determineRoute (HttpHost target, HttpRequest request, HttpContext context) throws HttpException {
        return defaultProxyRoutePlanner.determineRoute (target, request, context);
    }
}

总结......

  • 我需要在Feign上创建相同的ProxyRoutePlanner配置。

已编辑 -

我创建了一个类

@Configuration
public class FeignConfiguration {

使用方法

@Bean
    @ConditionalOnMissingBean (CloseableHttpClient.class)
    public CloseableHttpClient httpClient () {
        DynamicProxyRoutePlanner routePlanner = getProxy ();
        CredentialsProvider credentialsProvider = getCredentials ();

        return HttpClients.custom ()
                .setDefaultCredentialsProvider (credentialsProvider)
                .setRoutePlanner (routePlanner) .build ();
    }

    private DynamicProxyRoutePlanner getProxy () {
        HttpHost proxy = new HttpHost (HOST_PROXY, PORT_PROXY);
        return new DynamicProxyRoutePlanner (proxy);
    }


    public CredentialsProvider getCredentials () {
        AuthCache authCache = new BasicAuthCache ();
        CredentialsProvider credsProvider = new BasicCredentialsProvider ();
        credsProvider.setCredentials (new AuthScope (HOST_PROXY, PORT_PROXY, AuthScope.ANY_HOST, "ntlm"),
                new NTCredentials (USER, PASS, "", DOMAIN));
        HttpClientContext context = HttpClientContext.create ();
        context.setCredentialsProvider (credsProvider);
        context.setAuthCache (authCache);
        return credsProvider;
    }

我已经重新安装了连接测试,但即使Feign似乎没有尝试使用代理设置,请参阅以下错误:

2018-04-25 09: 59: 10.494 ERROR 25309 --- [nio-9063-exec-2] oaccC [. [. [.] [DispatcherServlet]: Servlet.service () for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.RetryableException: Connection refused (Connection refused) executing POST http://sinaflor-api.des.basis.com.br/api/empreendimentos] with root cause

java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect (Native Method) ~ [na: 1.8.0_171]
at java.net.AbstractPlainSocketImpl.doConnect (AbstractPlainSocketImpl.java:350) ~ [na: 1.8.0_171]
at java.net.AbstractPlainSocketImpl.connectToAddress (AbstractPlainSocketImpl.java:206) ~ [na: 1.8.0_171]
at java.net.AbstractPlainSocketImpl.connect (AbstractPlainSocketImpl.java:188) ~ [na: 1.8.0_171]
at java.net.SocksSocketImpl.connect (SocksSocketImpl.java:392) ~ [na: 1.8.0_171]
at java.net.Socket.connect (Socket.java:589) ~ [na: 1.8.0_171]
at sun.net.NetworkClient.doConnect (NetworkClient.java:175) ~ [na: 1.8.0_171]
at sun.net.www.http.HttpClient.openServer (HttpClient.java:463) ~ [na: 1.8.0_171]
at sun.net.www.http.HttpClient.openServer (HttpClient.java:558) ~ [na: 1.8.0_171]
at sun.net.www.http.HttpClient. <init> (HttpClient.java:242) ~ [na: 1.8.0_171]
at sun.net.www.http.HttpClient.New (HttpClient.java:339) ~ [na: 1.8.0_171]
at sun.net.www.http.HttpClient.New (HttpClient.java:357) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient (HttpURLConnection.java:1220) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0 (HttpURLConnection.java:1156) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.plainConnect (HttpURLConnection.java:1050) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.connect (HttpURLConnection.java:984) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0 (HttpURLConnection.java:1334) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream (HttpURLConnection.java:1309) ~ [na: 1.8.0_171]
at feign.Client $ Default.convertAndSend (Client.java:133) ~ [feign-core-9.3.1.jar: na]
at feign.Client $ Default.execute (Client.java:73) ~ [feign-core-9.3.1.jar: na]
at feign.SynchronousMethodHandler.executeAndDecode (SynchronousMethodHandler.java:97) ~ [feign-core-9.3.1.jar: na]
at feign.SynchronousMethodHandler.invoke (SynchronousMethodHandler.java:76) ~ [feign-core-9.3.1.jar: na]
at feign.ReflectiveFeign $ FeignInvocationHandler.invoke (ReflectiveFeign.java:103) ~ [feign-core-9.3.1.jar: na]
at com.sun.proxy $ Proxy112.send (Unknown Source) ~ [na: na]

3 个答案:

答案 0 :(得分:1)

我能够使用okHttpClient解决假装中的代理配置,如下所示:

@Configuration
public class FeignConfigurationProxy {

    @Value("${url.proxy_host}")
    private String HOST_PROXY;
    @Value("${url.proxy_port}")
    private Integer PORT_PROXY;

    private OkHttpClient okHttpClient;
    private Proxy proxy;

    @PostConstruct
    public void init() {
        buildProxy();
        buildOkHttpClient();
    }

    @Bean(name = "feign")
    public Feign buildClient() {
        return Feign.builder().client(new feign.okhttp.OkHttpClient(okHttpClient)).build();
    }


    @Bean(name = "okhttpclient")
    public OkHttpClient okHttpClient() {
        return okHttpClient;
    }

    public void buildOkHttpClient() {
        buildProxy();
        okHttpClient = new OkHttpClient.Builder().proxy(proxy).build();
    }

    public void buildProxy() {
        proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(HOST_PROXY, PORT_PROXY));
    }

}
pom.xml中的

我添加了依赖项:

<dependency>
<groupId> io.github.openfeign </ groupId>
<artifactId> feign-okhttp </ artifactId>
<version> 9.5.0 </ version>
</ dependency>
<dependency>
<groupId> com.squareup.okhttp3 </ groupId>
<artifactId> okhttp </ artifactId>
<version> 3.10.0 </ version>
</ dependency>

答案 1 :(得分:1)

Spring cloud openfeign 支持三种底层实现:

  1. 默认
  2. ApacheHttpClient
  3. OkHttpClient

根据您的项目中使用的实现,以下是您如何配置 feign 客户端以使用 HTTP 代理: 技巧:您配置 feign 客户端,然后覆盖 Spring 应用程序上下文中的默认客户端 bean。

默认:

import feign.Client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.InetSocketAddress;
import java.net.Proxy;

@Configuration
public class FeignConfiguration {
  ...
  @Bean
  public Client feignClient() {
      return new Client.Proxied(null, null, 
                 new Proxy(Proxy.Type.HTTP,
                     new InetSocketAddress(proxyHost, proxyPort)));
  }
}

使用 ApacheHttpClient:

<块引用>

当您的 feign.httpclient.enabled: trueapplication.yml 中的 pom.xml 位于 build.gradle 及以下时:

pom.xml
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

build.gradle
implementation 'io.github.openfeign:feign-httpclient'


import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.http.HttpHost;

@Configuration
public class FeignConfiguration {
  ...
  @Bean
  public CloseableHttpClient feignClient() {
    return HttpClientBuilder.create().setProxy(
              new HttpHost(proxyHost, proxyPort)).build();
  }
}

使用 OkHttpClient:

<块引用>

当您的 feign.okhttp.enabled: trueapplication.yml 中的 pom.xml 位于 build.gradle 及以下时:

pom.xml
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
</dependency>

build.gradle
implementation 'io.github.openfeign:feign-okhttp'


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.InetSocketAddress;
import java.net.Proxy;
import okhttp3.OkHttpClient;

@Configuration
public class FeignConfiguration {
  ...
  @Bean
  public OkHttpClient okHttpClient() {
    return new OkHttpClient.Builder()
       .proxy(new Proxy(Proxy.Type.HTTP, 
             new InetSocketAddress(proxyHost, proxyPort)))
       .build();
  }
}

答案 2 :(得分:0)

只需将您的CloseableHttpClient定义为Spring Bean。

从Spring Cloud Edgware 版本开始,如果将CloseableHttpClient定义为Spring Bean,则将使用它而不是默认值。