PUBLIC OBJECT

Java’s new HTTP client is upside down

One of Java 9’s new features is a replacement for HttpURLConnection. And while I’m thrilled to get rid of that old garbage its replacement has its own surprises.

The Good

The API is small. The new package is java.net.http and the Javadoc shows only 12 new HTTP types plus 6 more for websockets.

It implements HTTP/2. There’s NIO and java.util.concurrent APIs throughout so it might be efficient for many parallel requests.

There’s builders! And an HttpClient type. Java’s built in TLS stack has been upgraded to support ALPN which means it can negotiate HTTP/2 without the awkward jetty-alpn bootclasspath trick.

The Bad

There’s an HttpHeaders type, but it’s an interface and not an immutable value object. There’s no builder for the headers, only for the HttpRequest.

Though HttpURLConnection is now unnecessary, this new client continues to rely on several of its obsolete support classes. The most frustrating of these is URI, which can’t represent real-world URLs such as those in Google’s image charts. And if you want query parameters you have to concatenate strings.

Many useful knobs and features are absent from the API. There’s no socket factory, no connection pool, and no way to plug in a response cache.

The Ugly

This API is hostile to unit testing. You can’t construct an HttpResponse. If you want one you’ll need a webserver.

You can’t write the request body to an OutputStream. Instead, there’s a callback-driven BodyProcessor interface where your code provides bytes as they’re requested. Most applications will need to fully buffer requests to cope with this. Otherwise your body writer must be passive which breaks composability.

Asymmetrically, there is an API to get the response body as an InputStream. But sadly that API is discouraged:

“This mechanism is provided primarily for backwards compatibility for code that expects InputStream. It is recommended for better performance to use one of the other response processor implementations.”

To contrast, OkHttp performs just fine with streams. And for very high concurrency you can use it with Comsat.

TL;DR

Oracle’s new HTTP client brings new TLS features that make it easier for third-party HTTP libraries to do their job. The rest of it is dead weight.