How to add a http proxy for Jersey2 Client
Asked Answered
K

7

18

It's easy to set a proxy for client on Jersey1.x:

config.getProperties().put(ApacheHttpClientConfig.PROPERTY_PROXY_URI, proxyUrl);

But how to add a http proxy for Jersey2.x client? I checked the source code and didn't find the implementation does that in:

org.glassfish.jersey.client.HttpUrlConnector

Thanks!

Kiloton answered 22/9, 2013 at 10:6 Comment(0)
K
13

To set different proxy on runtime is not good solution. Accordingly, I used apache connector to do so:

add apache connector dependency defined:

<dependency>
 <groupId>org.glassfish.jersey.connectors</groupId>
 <artifactId>jersey-apache-connector</artifactId>
</dependency>

add apache connector to client

config.property(ApacheClientProperties.PROXY_URI, proxyUrl); 
Connector connector = new ApacheConnector(config); 
config.connector(connector); 
Kiloton answered 25/9, 2013 at 2:10 Comment(1)
It works fine with apache connector 2.17 if ClientProperties.PROXY_URI starts with http://Fassold
N
18

thanks @feuyeux, the solution is work for me, ps, the code below is works in the proxy with http basic auth:

    ClientConfig config = new ClientConfig();
    config.connectorProvider(new ApacheConnectorProvider());
    config.property(ClientProperties.PROXY_URI, proxy);
    config.property(ClientProperties.PROXY_USERNAME,user);
    config.property(ClientProperties.PROXY_PASSWORD,pass);
    Client client = JerseyClientBuilder.newClient(config);

hope to help others

Neu answered 15/5, 2015 at 5:40 Comment(0)
K
13

To set different proxy on runtime is not good solution. Accordingly, I used apache connector to do so:

add apache connector dependency defined:

<dependency>
 <groupId>org.glassfish.jersey.connectors</groupId>
 <artifactId>jersey-apache-connector</artifactId>
</dependency>

add apache connector to client

config.property(ApacheClientProperties.PROXY_URI, proxyUrl); 
Connector connector = new ApacheConnector(config); 
config.connector(connector); 
Kiloton answered 25/9, 2013 at 2:10 Comment(1)
It works fine with apache connector 2.17 if ClientProperties.PROXY_URI starts with http://Fassold
C
9

If you use jersey 2.0 default http connector(which is JDK Http(s)URLConnection). You could just simple configure the proxy like:

    System.setProperty ("http.proxyHost", "proxy_server");
    System.setProperty ("http.proxyPort", "proxy_port");

For other implementations of http connector (Apache HTTP Client and Grizzly Asynchronous Client), I haven't tried before. But I think you could follow the instruction by http connector itself.

Celestine answered 24/9, 2013 at 2:51 Comment(4)
Thanks for your help, I think it should be good solution for single environment, but if I need to abstract my biz client, and the proxy server is a parameter, doesn't it work in every time setting? Is there synchronized issue?Kiloton
you could use a properties file to configure the parameters. or you could use -Dhttp.proxyHost="proxy_server" and -Dhttp.proxyPort="proxy_port"Celestine
To set different proxy on runtime is not good solution. Accordingly, I used apache connector to do so: <dependency> <groupId>org.glassfish.jersey.connectors</groupId> <artifactId>jersey-apache-connector</artifactId> </dependency> config.property(ApacheClientProperties.PROXY_URI, proxyUrl); Connector connector = new ApacheConnector(config); config.connector(connector);Kiloton
"To set different proxy on runtime is not good solution" - why not? what if I need to make multiple connections via different networks? Setting at runtime is essential in this case.Kamerad
O
5

An alternative without include jersey-apache-connector

public class Sample {

  public static void main(String[] args) {

    // you can skip AUTH filter if not required
    ClientConfig config = new ClientConfig(new SampleProxyAuthFilter());
    config.connectorProvider(
        new HttpUrlConnectorProvider().connectionFactory(new SampleConnectionFactory()));

    Client client = ClientBuilder.newClient(config);

    // there you go
  }
}

class SampleConnectionFactory implements HttpUrlConnectorProvider.ConnectionFactory {
  @Override
  public HttpURLConnection getConnection(URL url) throws IOException {
    return (HttpURLConnection) url
        .openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("host", 8080)));
  }
}

class SampleProxyAuthFilter implements ClientRequestFilter {

  @Override
  public void filter(ClientRequestContext requestContext) throws IOException {
    requestContext.getHeaders().add("Proxy-Authorization", "authentication");
  }
}
Optimum answered 26/7, 2018 at 13:50 Comment(3)
So far, this is the only add a proxy solution that worked in Jersey 2 code -- thank you.Trapezius
Does this work for using a proxy over TSL/SSL? I tried changing to Proxy.Type.SOCKS and it seems to just stall out. I don't want to use the system properties since I need to make some other calls over HTTPS that will not use the proxy.Biocellate
@mekane84, the Proxy.Type.HTTP means the proxy server is http, it works fine when I visit https(TSL/SSL) server with it.Optimum
C
4

This solution has worked for me

pom.xml

<dependency>
    <groupId>org.glassfish.jersey.connectors</groupId>
    <artifactId>jersey-apache-connector</artifactId>
    <version>2.17</version>
</dependency>

Java

ClientConfig config = new ClientConfig();
config.property( ClientProperties.PROXY_URI, "http://_YOUR_URI_:_YOUR_PORT_" );
config.connectorProvider( new ApacheConnectorProvider() );
Client client = ClientBuilder.newClient( config );

Hope that helps :)

Connally answered 29/1, 2018 at 11:11 Comment(1)
Thank you Halayem Anis. Your answer really helped me.Spontaneity
D
2

The issue with the standard Jersey 2.x proxy configuration is it doesn't allow nonProxyHosts option. It doesn't allow to separate http and https calls too, but these limitations were ok for me.

To be able to reuse the JVM proxy properties (-Dhttp.proxyHost, ...) instead of specifying dedicated Jersey params, you can register a specific Jersey config's connector (regarding to the previous answers, it may or may not have been out of the box in the past, but it isn't on the current 2.30 jersey version):

In maven3 pom.xml:

  <properties>
    <jersey.version>2.30.1</jersey.version>
  </properties>
  <dependency>
    <groupId>org.glassfish.jersey.connectors</groupId>
    <artifactId>jersey-apache-connector</artifactId>
    <version>${jersey.version}</version>
  </dependency>

In your Jersey code:

  • add the ApacheConnectorProvider
  • register a new ApacheHttpClientBuilderConfigurator which set the .useSystemProperties() flag on the underlying HttpClient's client
ClientConfig config = new ClientConfig()

    // Apache connector to active the proxy settings
    // EDIT: comment this line as it seems to be useless when using ApacheHttpClientBuilderConfigurator (below) and it provokes random hangs
    //.connectorProvider(new ApacheConnectorProvider())

    // Register specific features and black-magic Jersey behaviors
    //.register(Xxxx.class)
    //.register(Yyyy.class)

    // By registering this magic lambda (Found after debugging both Jersey and HttpClient)
    // We fallback on the regular JVM proxy settings properties, and avoid the restricted
    // jersey properties.
    //
    // Jersey proxy properties are restrictive because they ignore nonProxyHosts.
    // Jersey properties:
    // .property(ClientProperties.PROXY_URI, "http://host:port")
    // .property(ClientProperties.PROXY_USERNAME, "myProxyUser")
    // .property(ClientProperties.PROXY_PASSWORD, "myProxyPassword")
    //
    // To be able to take into account regular JVM proxy properties:
    // For HTTP: -Dhttp.proxyHost=http.proxy.example.com -Dhttp.proxyPort=10080
    // For HTTPS: -Dhttps.proxyHost=https.proxy.example.com -Dhttps.proxyPort=10443
    // Common for BOTH http and https: -Dhttp.nonProxyHosts=foo.example.com|bar.example.com|*baz.example.com
    // Auth NTLM: -Dhttp.proxyUser=MyDomain/username or -Dhttp.auth.ntlm.domain=MyDomain
    // Auth Basic: -Dhttp.proxyUser=username or -Dhttp.proxyPassword=password
    .register(
        ((ApacheHttpClientBuilderConfigurator)
            httpClientBuilder -> {
                  RequestConfig requestConfig =
                      RequestConfig.custom()
                          .setConnectTimeout(5000)
                          .setConnectionRequestTimeout(5000)
                          .setSocketTimeout(5000)
                          .build();
                  httpClientBuilder.setDefaultRequestConfig(requestConfig);
                  httpClientBuilder.useSystemProperties();
              return httpClientBuilder;
            }))

    // Register other properties
    //.property(ClientProperties.CONNECT_TIMEOUT, 5000)
    //.property(ClientProperties.READ_TIMEOUT, 5000)
    //.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);
Dionnadionne answered 5/5, 2020 at 8:50 Comment(0)
S
0

Complete solution

I tried everything and the only thing that actually worked out is this setup:

First thing

  • adding jersey-apache-connector to pom.xml
<dependency>
    <groupId>org.glassfish.jersey.connectors</groupId>
    <artifactId>jersey-apache-connector</artifactId>
    <version>2.51.1</version>
</dependency>

Second thing

  • adding/updating httpclient version in pom.xml (important part because of the missing classes errors in lower versions! - see link)
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.2</version>
</dependency>

Third thing

  • using libraries in code
ClientConfig config = new ClientConfig(); 
config.connectorProvider(new ApacheConnectorProvider()); 
config.property(ClientProperties.PROXY_URI, proxy); 
config.property(ClientProperties.PROXY_USERNAME,user); 
config.property(ClientProperties.PROXY_PASSWORD,pass); 
Client client = JerseyClientBuilder.newClient(config);
Silicle answered 8/2, 2023 at 7:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.