java 配置代理到 Jersey 客户端

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10385259/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 00:48:33  来源:igfitidea点击:

Configure proxy to Jersey client

javaproxyjersey

提问by danieln

I would like to configure a proxy server to my Jersey client.
I don't want to configure the proxy to the whole application (using JVM arguments such as http.proxyHost), and Id'e rather not use Apache client.
I read herethat there is an option to do it by providing HttpUrlConnection via HttpUrlConnectionFactory, but I couldn't find any code example.
Does anyone know how can I do it?
Thanks!

我想为我的 Jersey 客户端配置一个代理服务器。
我不想为整个应用程序配置代理(使用 JVM 参数,例如 http.proxyHost),我宁愿不使用 Apache 客户端。
在这里读到有一个选项可以通过 HttpUrlConnectionFactory 提供 HttpUrlConnection,但我找不到任何代码示例。
有谁知道我该怎么做?
谢谢!

回答by danieln

With the help of Luca, I got it done:

在 Luca 的帮助下,我完成了:

  1. Implement HttpURLConnectionFactory, and override the method getHttpURLConnection, my implementation is (thanks to Luca):

    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 3128));
    return new HttpURLConnection(url, proxy);
    
  2. Before instantiating the Jersey Client, create a new URLConnectionClientHandler, and provide your HttpURLConnectionFactoryin its constructor. Then create a new Client, and provide your ClientHandlerin the Clientconstructor. My code:

    URLConnectionClientHandler urlConnectionClientHandler = new URLConnectionClientHandler(new MyHttpURLConnectionFactory());
    _client = new Client(urlConnectionClientHandler);
    
  1. 实现HttpURLConnectionFactory,并覆盖方法getHttpURLConnection,我的实现是(感谢 Luca):

    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 3128));
    return new HttpURLConnection(url, proxy);
    
  2. 在实例化 Jersey 客户端之前,创建一个新的URLConnectionClientHandler,并HttpURLConnectionFactory在其构造函数中提供您的。然后创建一个 new Client,并ClientHandlerClient构造函数中提供您的。我的代码:

    URLConnectionClientHandler urlConnectionClientHandler = new URLConnectionClientHandler(new MyHttpURLConnectionFactory());
    _client = new Client(urlConnectionClientHandler);
    

Hope that's help.

希望这有帮助。

回答by AIMABLE

First of all I created this class

首先我创建了这个类

    import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory;
    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.net.InetSocketAddress;
    import java.net.Proxy;
    import java.net.URL;
    import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;

/**
 *
 * @author Aimable
 */
public class ConnectionFactory implements HttpURLConnectionFactory {

    Proxy proxy;

    String proxyHost;

    Integer proxyPort;

    SSLContext sslContext;

    public ConnectionFactory() {
    }

    public ConnectionFactory(String proxyHost, Integer proxyPort) {
        this.proxyHost = proxyHost;
        this.proxyPort = proxyPort;
    }

    private void initializeProxy() {
        proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
    }

    @Override
    public HttpURLConnection getHttpURLConnection(URL url) throws IOException {
        initializeProxy();
        HttpURLConnection con = (HttpURLConnection) url.openConnection(proxy);
        if (con instanceof HttpsURLConnection) {
            System.out.println("The valus is....");
            HttpsURLConnection httpsCon = (HttpsURLConnection) url.openConnection(proxy);
            httpsCon.setHostnameVerifier(getHostnameVerifier());
            httpsCon.setSSLSocketFactory(getSslContext().getSocketFactory());
            return httpsCon;
        } else {
            return con;
        }

    }

    public SSLContext getSslContext() {
        try {
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new TrustManager[]{new SecureTrustManager()}, new SecureRandom());
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(ConnectionFactory.class.getName()).log(Level.SEVERE, null, ex);
        } catch (KeyManagementException ex) {
            Logger.getLogger(ConnectionFactory.class.getName()).log(Level.SEVERE, null, ex);
        }
        return sslContext;
    }

    private HostnameVerifier getHostnameVerifier() {
        return new HostnameVerifier() {
            @Override
            public boolean verify(String hostname,
                    javax.net.ssl.SSLSession sslSession) {
                return true;
            }
        };
    }

}

then I also create another class called SecureTrustManager

然后我还创建了另一个名为 SecureTrustManager 的类

    import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;

/**
 *
 * @author Aimable
 */
public class SecureTrustManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
    }

    @Override
    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }

    public boolean isClientTrusted(X509Certificate[] arg0) {
        return true;
    }

    public boolean isServerTrusted(X509Certificate[] arg0) {
        return true;
    }

}

then after creation this class i'm calling the client like this

然后在创建这个类之后我像这样调用客户端

URLConnectionClientHandler cc = new URLConnectionClientHandler(new ConnectionFactory(webProxy.getWebserviceProxyHost(), webProxy.getWebserviceProxyPort()));
    client = new Client(cc);
    client.setConnectTimeout(2000000);

replace webProxy.getWeserviceHost by your proxyHost and webProxy.getWebserviceProxyPort() by the proxy port.

将 webProxy.getWeserviceHost 替换为您的 proxyHost,将 webProxy.getWebserviceProxyPort() 替换为代理端口。

This worked for me and it should work also for you. Note that i'm using Jersey 1.8 but it should also work for Jersey 2

这对我有用,也应该对你有用。请注意,我使用的是 Jersey 1.8 但它也适用于 Jersey 2

回答by Luca

Try

尝试

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));
conn = new URL(url).openConnection(proxy);