Platinum Partner
java,apache,fluent,httpclient,connection manager

Fluency and Control with HttpClient

The new HttpClient provides a fluent interface that is quite intuitive.  However, any non-trivial implementation soon starts to miss the flexibility of configuring the connection manager.  As a pre-configured HttpClient can be passed into the fluent Executor each time, it is overhead to configure it each time. 

Here is a sample of a simple fluent Request from the tutorial:

String page = Request.Get("http://somehost/")
     .connectTimeout(1000)
     .socketTimeout(1000)
     .execute().returnContent().asString();

To maintain client-side state (cookies, authentication) between requests, the fluent Executor helps by keeping a cookie store and setting up other types of authentication:

Executor executor = Executor.newInstance()
    .authPreemptive(new HttpHost("myproxy", 8080));
executor.execute(Request.Post("http://somehost/some-form))
    .addHeader("X-Custom-header", "stuff")
    .execute().saveContent(new File("result.dump"));
executor.execute(Request.Get("http://somehost/"))
    .returnContent().asString();

Executor provides a HttpClient constructor but should we be setting one up each time we want to use an Executor 'conversation'.  Extending it in the singleton pattern provided an instance that was configured just once:

Executor executor = Executor.newInstance(OurHttpClient.getInstance());
page = executor.execute(Request . . . . . 
doc = Jsoup.parse(page);
doLogout(excutor);  //passing around the Executor to different methods
executor.clearCookies(); // in case it needs to be cleared

And relevant snippets from the singleton OurHttpClient

private static OurHttpClient instance;
private static PoolingClientConnectionManager cm;

private OurHttpClient(ClientConnectionManager connMgr) { // singleton
    super(connMgr)
}

private static void initialize() { // set up SSL and regular ports with any quirks
    SchemeRegistry . . . . 
    cm = new PoolingClientConnectionManager(schemeRegistry);
    cm.setDefaultMaxPerRoute(MAX_CONNS_ROUTE);
    cm.setMaxTotal(MAX_CONNS_TOTAL);
}


// The public getInstance method
public static OurHttpClient getInstance() {
    if (instance == null) {
        initialize(); // will create the Connection Manager
    }
    instance = new OurHttpClient(cm);  
     // an example of some other customization 
    instance.setRedirectStrategy(new LaxRedirectStrategy());
     // an example of other features being set up
    if (PROXY_HOST != null !"".equals(PROXY_HOST)) {

    }
    return instance;
}

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}