JDK-8181784 : JEP 321: HTTP Client
  • Type: JEP
  • Component: core-libs
  • Sub-Component: java.net
  • Priority: P2
  • Status: Closed
  • Resolution: Delivered
  • Fix Versions: 11
  • Submitted: 2017-06-08
  • Updated: 2020-09-15
  • Resolved: 2018-09-27
Related Reports
Relates :  
Sub Tasks
JDK-8197564 :  
JDK-8209634 :  
Description
Summary
-------

Standardize the [incubated][JEP 11] HTTP Client API introduced in
JDK 9, via [JEP 110][JEP 110], and updated in JDK 10.

[JEP 11]: http://openjdk.java.net/jeps/11
[JEP 110]: http://openjdk.java.net/jeps/110


Goals
-----

In addition to the [goals of JEP 110][110-Goals], this JEP will:

  - Take into account feedback received on the incubated API,
  - Provide a standardized API, in the  `java.net.http` package,
    based upon the incubated API, and
  - Remove the incubated API.

[110-Goals]: http://openjdk.java.net/jeps/110#Goals


Motivation
----------

The motivation of this JEP remains the same as that of the
[motivation of JEP 110][110-Motivation].

[110-Motivation]: http://openjdk.java.net/jeps/110#Motivation


Description
-----------

This JEP proposes to standardize the HTTP Client API that was introduced
as an incubating API in JDK 9 and updated in JDK 10. The incubating API
has received a number of rounds of feedback that have resulted in
significant improvements, but at a high level it remains largely the
same. The API provides non-blocking request and response semantics
through `CompletableFuture`s, which can be chained to trigger dependent
actions. Back-pressure and flow-control of request and response bodies is
provided for via the Platform's [reactive-streams][rx] support in the
`java.util.concurrent.Flow` API.

While incubating in JDK 9 and JDK 10, the implementation has been almost
completely rewritten. The implementation is now completely asynchronous
(the previous HTTP/1.1 implementation was blocking). Use of the RX Flow
concept has been pushed down into the implementation, which eliminated
many of the original custom concepts needed to support HTTP/2. The flow
of data can now be more easily traced, from the user-level request
publishers and response subscribers all the way down to the underlying
socket.  This significantly reduces the number of concepts and complexity
in the code, and maximizes the possibility of reuse between HTTP/1.1 and
HTTP/2.

The module name and the package name of the standard API will be
`java.net.http`.

### Changes over what was incubated in JDK 10

1. The predefined implementation of `BodyPublisher`, `BodyHandler`,
and `BodySubscriber`, created through static factory methods, have
been moved out to separate non-instantiable utility factory classes,
following the pluralized naming convention. This improves readability
of these relatively small interfaces.

2. The names of the static factory methods have also been updated
along the following broad categories:

  - `fromXxx`: Adapters from standard Subscriber, e.g. takes a
  `Flow.Subscriber` returns a `BodySubscriber`.

  - `ofXxx`: Factories that create a new pre-defined
  `Body[Publisher|Handler|Subscriber]` that perform useful common
  tasks, such as handling the response body as a String, or streaming the
  body to a File.

  - other: Combinators (takes a `BodySubscriber` returns a
  `BodySubscriber`) and other useful operations.

3. A few `BodyHandler`s and corresponding `BodySubscriber`s have been
added, to improve usability in common scenarios:

  * `discard(Object replacement)` combined discarding/ignoring the
  response body and allowing a given replacement. Feedback has
  indicated that this could appear confusing. It has been removed
  and replaced with two separate handlers: 1) `discarding()`, and 2)
  `replacing(Object replacement)`.

  * Added `ofLines()` that returns a `BodyHandler<Stream<String>>`,
  to support streaming of response body as a `Stream` of lines,
  line by line. Provides similar semantics to that of
  `BufferedReader.lines()`.

  * Added `fromLineSubscriber���`, that supports adaptation of
  response body to a `Flow.Subscriber` of `String` lines.

  * Added `BodySubscriber.mapping` for general purpose mapping from
  one response body type to another.

4. The push promise support has been re-worked to reduce its impact on
the API and bring it more in line with regular request/responses.
Specifically, the `MultiSubscriber` and `MultiResultMap` have been
removed. Push promises are now handled through a functional interface,
`PushPromiseHandler`, that is optionally given during a send
operation.

5. The `HttpClient.Redirect` policy has been simplified, by replacing
`SAME_PROTOCOL` and `SECURE` policies, with `NORMAL`.  It has been
observed that the previously named `SECURE` was not really appropriately
named and should be renamed to `NORMAL`, since it will likely be
suitable for most normal cases. Given the newly named, aforementioned,
`NORMAL`, `SAME_PROTOCOL` appears oddly named, possibly confusing, and
not likely to be used.

6. `WebSocket.MessagePart` has been removed. This enum was used on the
receiving side to indicate whether the delivery of a message is
complete, or not. It is asymmetric with the sending side, which uses a
simple boolean for this purpose. Additionally, it has been observed that
handling received messages with a simple boolean significantly reduces
and simplifies the receiving code logic. Determination of messages being
delivered as a `WHOLE`, one of the benefits and the main purposes for
the aforementioned `MessagePart`, has proved to not carry its own
weight.

Further specifics on the API can be found in [JEP 110][110-Description],
at the [latest API javadoc][doc], or the networking group's
[JDK HTTP Client][jdkhttp] page.

[110-Description]: http://openjdk.java.net/jeps/110#Description
[rx]: http://www.reactive-streams.org
[doc]: http://cr.openjdk.java.net/~chegar/httpclient/02/javadoc/api/java.net.http/module-summary.html
[jdkhttp]: http://openjdk.java.net/groups/net/httpclient/


Testing
-------

Existing tests for the incubated API will be updated to use the
new standard API. Additional tests will be added to cover all scenarios
supported, specifically the upgrade and downgrade between HTTP/1.1 and
HTTP/2.


Risks and Assumptions
---------------------

Code that currently depends upon the incubated HTTP Client API will need
to be updated, at the very minimum to change its package imports. This is
no different than for any other incubated feature. Code depending upon
incubating modules already receives an appropriate warning at both
compile time and run time.

Comments
Some learning material available at: https://www.youtube.com/user/java AND https://developer.oracle.com/java11 1) Introduction to the Java 11 HTTP Client with Chris Hegarty https://www.youtube.com/watch?v=sZSdWq490Vw 2) Road to the Java 11 HTTP Client with Chris Hegarty https://www.youtube.com/watch?v=9JxMxfKBr20 3) Handling Response Data with the Java 11 HTTP Client with Chris Hegarty https://www.youtube.com/watch?v=JupZ8B74FPw
27-09-2018

Note to reviewers: while the individual section links to JEP 110 are not ideal, they have been added to reduce, as much as possible, the duplication of text between these two related JEPs.
08-11-2017