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

问题描述 投票:0回答:4

在 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]
rest configure http-proxy spring-cloud-feign feign
4个回答
4
投票

我能够使用 okHttpClient 解析 feign 中的代理配置,如下所示:

@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>

4
投票

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: true
application.yml
中包含
pom.xml
及以下内容时:

build.gradle
使用 OkHttpClient:

当您的
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(); } }

feign.okhttp.enabled: true
中包含
application.yml
及以下内容时:

pom.xml

只需将您的 
build.gradle

0
投票

从 Spring Cloud

Edgware
版本开始,如果您将

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(); } }

定义为 Spring Bean,则将使用它而不是默认的

在我的案例中使用代理隧道到另一个网址


0
投票

CloseableHttpClient


    

© www.soinside.com 2019 - 2024. All rights reserved.