简体   繁体   中英

Jersey Client + set proxy

Hi I've a jersey client which i use to upload a file. I tried using it locally and everything works fine. But in production environment i've to set proxy. I browsed thru few pages but could not get exact solution. Can someone pls help me with this?

here is my client code:

File file = new File("e:\\test.zip");
FormDataMultiPart part = new FormDataMultiPart();
part.bodyPart(new FileDataBodyPart("file", file, MediaType.APPLICATION_OCTET_STREAM_TYPE));
WebResource resource = null;

if (proxy.equals("yes")) {
    // How do i configure client in this case?
} else {
    // this uses system proxy i guess
    resource = Client.create().resource(url);
}

String response = (String) resource.type(MediaType.MULTIPART_FORM_DATA_TYPE).post(String.class, part);
System.out.println(response);

There is an easier approach, if you want to avoid more libraries in legacy projects and there is no need for Proxy Authentication:

First you need a class which implements HttpURLConnectionFactory :

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;

import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory;


public class ConnectionFactory implements HttpURLConnectionFactory {

    Proxy proxy;

    private void initializeProxy() {
        proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("myproxy.com", 3128));
    }

    public HttpURLConnection getHttpURLConnection(URL url) throws IOException {
        initializeProxy();
        return (HttpURLConnection) url.openConnection(proxy);
    }
}

Second is to instantiate an com.sun.jersey.client.urlconnection.URLConnectionHandler

URLConnectionClientHandler ch  = new URLConnectionClientHandler(new ConnectionFactory());

and third is to use the Client Constructor instead of Client.create :

Client client = new Client(ch);

Of course you can customize the initializing of the Proxy in the ConnectionFactory .

luckyluke answer shall work. Here my version:

ClientConfig config = new DefaultClientConfig();
Client client = new Client(new URLConnectionClientHandler(
        new HttpURLConnectionFactory() {
    Proxy p = null;
    @Override
    public HttpURLConnection getHttpURLConnection(URL url)
            throws IOException {
        if (p == null) {
            if (System.getProperties().containsKey("http.proxyHost")) {
                p = new Proxy(Proxy.Type.HTTP,
                        new InetSocketAddress(
                        System.getProperty("http.proxyHost"),
                        Integer.getInteger("http.proxyPort", 80)));
            } else {
                p = Proxy.NO_PROXY;
            }
        }
        return (HttpURLConnection) url.openConnection(p);
    }
}), config);

Here you go:

 DefaultApacheHttpClient4Config config = new DefaultApacheHttpClient4Config();
      config.getProperties().put(
      ApacheHttpClient4Config.PROPERTY_PROXY_URI, 
      "PROXY_URL"
 );

 config.getProperties().put(
      ApacheHttpClient4Config.PROPERTY_PROXY_USERNAME, 
      "PROXY_USER"
 );

 config.getProperties().put(
      ApacheHttpClient4Config.PROPERTY_PROXY_PASSWORD, 
      "PROXY_PASS"
 );     

 Client c = ApacheHttpClient4.create(config);
 WebResource r = c.resource("https://www.google.com/");
System.setProperty("http.proxyHost","your proxy url");
System.setProperty("http.proxyPort", "your proxy port");

I took user67871 and changed it a bit. What is nice about this approach is that it works with the system proxy on Windows. If you're on Windows and you configure a proxy in IE then this code will pick that up. When you are running Fiddler it also sets the system proxy so this makes it really easy to use Jersey and Fiddler together.

    Client client = new Client(new URLConnectionClientHandler(
            new HttpURLConnectionFactory() {
        Proxy p = null;

        @Override
        public HttpURLConnection getHttpURLConnection(URL url)
                throws IOException {
            try {
                if (p == null) {
                    List<Proxy> proxies = ProxySelector.getDefault().select(url.toURI());
                    if (proxies != null) {
                        // just use the first one, I don't know if we should sometimes use a different one
                        p = proxies.get(0);
                    }
                    if (p == null) {
                        p = Proxy.NO_PROXY;
                    }
                }
                return (HttpURLConnection) url.openConnection(p);
            } catch (URISyntaxException ex) {
                throw new IOException(ex);
            }
        }
    }), config);

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

    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.

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

SDolgy. I did this who add 3 features in the Jersey client instantiation: Enables SSL TLSv1.1 (JVM >= 1.7 needed), Configure conex. pooling. to increase conections, Set a system proxy.

 # My props file    
 # CONFIGURAR EL CLIENTE
 #PROXY_URI=http://5.5.5.5:8080
 #SECURITY_PROTOCOL=TLSv1.2
 #POOLING_HTTP_CLIENT_CONNECTION_MANAGER.MAXTOTAL=200
 #POOLING_HTTP_CLIENT_CONNECTION_MANAGER.DEFAULTMAXPERROUTE=20

 import java.util.Properties;
 import javax.net.ssl.SSLContext;
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;

 import org.apache.http.config.Registry;
 import org.apache.http.config.RegistryBuilder;
 import org.apache.http.conn.socket.ConnectionSocketFactory;
 import org.apache.http.conn.socket.PlainConnectionSocketFactory;
 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

 import org.glassfish.jersey.SslConfigurator;
 import org.glassfish.jersey.apache.connector.ApacheClientProperties;
 import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.ClientProperties;
 import org.glassfish.jersey.jackson.JacksonFeature;

 public class JerseyClientHelper {
     private static Client cliente;
     private static final Properties configuracion = SForceConfiguration.getInstance();

     public static synchronized Client getInstance() {
         if (cliente == null) {            
             SSLContext sslContext = SslConfigurator.newInstance().securityProtocol(configuracion.getProperty("SECURITY_PROTOCOL")).createSSLContext(); // Usar TLSv1.2

             SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
             Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
             .register("http", PlainConnectionSocketFactory.getSocketFactory())
             .register("https", socketFactory)
             .build();

             // Para configurar las conexiones simultaneas al servidor
             int maxTotal = Integer.parseInt(configuracion.getProperty("POOLING_HTTP_CLIENT_CONNECTION_MANAGER.MAXTOTAL"));
             int defaultMaxPerRoute = Integer.parseInt(configuracion.getProperty("POOLING_HTTP_CLIENT_CONNECTION_MANAGER.DEFAULTMAXPERROUTE"));
             PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
             connectionManager.setMaxTotal(maxTotal);
             connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);

             ClientConfig config = new ClientConfig();
             config.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);
             config.connectorProvider(new ApacheConnectorProvider());
             config.property(ClientProperties.PROXY_URI, configuracion.getProperty("PROXY_URI")); // Debemos poner el PROXY del sistema


             cliente = ClientBuilder.newBuilder().sslContext(sslContext).withConfig(config).build();

         }        
         return cliente;
     }

 }

Was able to configure proxy overriding the client configuration provided to newClient. This worked for version 24.

return ClientBuilder.newClient(new ClientConfig().connectorProvider(new ConnectorProvider() {
    // figured this out from digging through jersey source code
    @Override
    public Connector getConnector(Client client, Configuration runtimeConfig) {
        HttpUrlConnectorProvider customConnProv = new HttpUrlConnectorProvider();
        customConnProv.connectionFactory(new ConnectionFactory() {
            @Override
            public HttpURLConnection getConnection(java.net.URL url) throws IOException {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
                return (HttpURLConnection) url.openConnection(proxy);
            }
        });
        return customConnProv.getConnector(client, runtimeConfig);
    }
}));

This is a simplified version of what others have proposed:

Proxy proxy = ...;
Client client = ClientBuilder.newClient(new ClientConfig()
    .connectorProvider(new HttpUrlConnectorProvider()
        .connectionFactory(url -> (HttpURLConnection) url.openConnection(proxy))));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM