How do Jersey-client and Apache HTTP Client compare?

carlspring picture carlspring · Sep 2, 2013 · Viewed 32.7k times · Source

First of all, I'm not trying to start a flame-war here. I know Jersey sufficiently well, but have hardly used httpclient.

What are the key differences between jersey-client and Apache's httpclient? In what areas is one better than the other? Is there a good comparison chart somewhere? Which one performs better with larger files (say 2048 MB)?

Many thanks for your comments!

Answer

Jk1 picture Jk1 · Oct 22, 2013

These two things probably should not be compared directly. Jersey is a REST-client, featuring full JAX-RS implementation, neat fluent API and a powerfull filter stack. Apache Http Client is a HTTP-client, perfect in managing low-level details like timeouts, complex proxy routes and connection polling. They act on a different levels of your protocol stack. When you're using Jersey there is always some kind of HTTP client backend involved. Given no backend explicitly, Jersey will use HttpUrlConnection as a default backend.

Jersey with HttpUrlConnection backend example:

Client client = Client.create();
WebResource webResource = client.resource("http://localhost:8080/path");
ClientResponse response = webResource.accept("application/json")
                                     .get(ClientResponse.class);

Jersey with Apache Http Client backend example:

HttpClient apacheClient = HttpClientBuilder.create().build();
Client client = new Client(new ApacheHttpClient4Handler(apacheClient,
                                                        new BasicCookieStore(),
                                                        true));
WebResource webResource = client.resource("http://localhost:8080/path");
ClientResponse response = webResource.accept("application/json")
                                     .get(ClientResponse.class);

Please note usage of Handler in the last example. This is a key integration abstraction for Jersey to incorporate and utilize various backends. First example uses URLConnectionClientHandler deep under the hood.

Speaking about performance and features it makes little sense to compare Apache Http Client with Jersey. One may want to compare different Jersey backends here, as Jersey itself is merely a wrapping API. I'd like to highlight some key differencies between HttpUrlConnection and Apache Http Client based on my own experience:

HttpUrlConnection

  • No external dependencies are necessary. This may be quite valuable on embedded or mobile platforms.
  • Extremely well documented everywhere
  • Has poorly designed API. HttpUrlConnection-based implementation is difficult to maintain and extend.
  • Many features are configured through JVM properties, some of which may be non-reconfigurable during runtime.
  • In some cases hopeless at handling timeouts. You may end up setting 10 different JVM properties for different timeouts and still get your connections hanging forever in some circumstances.
  • Since Gingerbread is a recommended http client API for Android.

Apache Http Client

  • For 3.X versions it's performance was somewhat similar to HttpUrlConnection. Version 4.1 contains lots of performance enchancements and performs way better than it's counterpart
  • Quite good at managing connection and data read timeouts
  • It's design follows Open/Closed Principle, so you can customize almost any part of HTTP processing with your own implementation. Examples: redirect strategies, retry strategies, custom cookie storages, interceptors for requests/responses, etc.
  • Provides rich proxy support with customizable route builders for complex multy-proxy paths
  • Has out of the box per-route connection pool. This may give a good performance benefit if SSL/TLS is used, especialy having hardware PKCS#11 tokens involved. HttpUrlConnection also has an internal pooling, but you have no tools to customize what or when to pool, no monitoring facilities to check the pool state.
  • Features detailed logging

Keep in mind, that it also possible to use other backends (e.g. for non-blocking clients) with Jersey if you have an appropriate com.sun.jersey.api.client.ClientHandler implementation.