Module jdk.incubator.httpclient
Package jdk.incubator.http

## Class HttpRequest

- java.lang.Object
- - jdk.incubator.http.HttpRequest

-     public abstract class HttpRequest
      extends Object

  Represents one HTTP request which can be sent to a server.
  Incubating Feature. Will be removed in a future release.

  `HttpRequest`s are built from `HttpRequest` `builder`s. `HttpRequest` builders are obtained by calling `HttpRequest.newBuilder`. A request's `URI`, headers and body can be set. Request bodies are provided through a `HttpRequest.BodyProcessor` object supplied to the `DELETE`, `POST` or `PUT` methods. `GET` does not take a body. Once all required parameters have been set in the builder, `HttpRequest.Builder.build()` is called to return the `HttpRequest`. Builders can also be copied and modified multiple times in order to build multiple related requests that differ in some parameters.

  Two simple, example HTTP interactions are shown below:

            HttpClient client = HttpClient.newHttpClient();

            // GET
            HttpResponse<String> response = client.send(
                HttpRequest
                    .newBuilder(new URI("http://www.foo.com/"))
                    .headers("Foo", "foovalue", "Bar", "barvalue")
                    .GET()
                    .build(),
                BodyHandler.asString()
            );
            int statusCode = response.statusCode();
            String body = response.body();

            // POST
            HttpResponse<Path> response = client.send(
                HttpRequest
                    .newBuilder(new URI("http://www.foo.com/"))
                    .headers("Foo", "foovalue", "Bar", "barvalue")
                    .POST(BodyProcessor.fromString("Hello world"))
                    .build(),
                BodyHandler.asFile(Paths.get("/path"))
            );
            int statusCode = response.statusCode();
            Path body = response.body(); // should be "/path"

  The request is sent and the response obtained by calling one of the following methods in `HttpClient`.

  - `HttpClient.send(HttpRequest, HttpResponse.BodyHandler)` blocks until the entire request has been sent and the response has been received.
  - `HttpClient.sendAsync(HttpRequest,HttpResponse.BodyHandler)` sends the request and receives the response asynchronously. Returns immediately with a `CompletableFuture`<`HttpResponse`>.
  - `HttpClient.sendAsync(HttpRequest,HttpResponse.MultiProcessor)` sends the request asynchronously, expecting multiple responses. This capability is of most relevance to HTTP/2 server push, but can be used for single responses (HTTP/1.1 or HTTP/2) also.

  Once a `HttpResponse` is received, the headers, response code and body (typically) are available. Whether the body has been read or not depends on the type `<T>` of the response body. See below.

  See below for discussion of synchronous versus asynchronous usage.

  Request bodies

  Request bodies are sent using one of the request processor implementations below provided in `HttpRequest.BodyProcessor`, or else a custom implementation can be used.

  - `fromByteArray(byte[])` from byte array
  - `fromByteArrays(Iterable)` from an Iterable of byte arrays
  - `fromFile(Path)` from the file located at the given Path
  - `fromString(String)` from a String
  - `fromInputStream`(`Supplier`< `InputStream`>) from an InputStream obtained from a Supplier
  - `noBody()` no request body is sent

  Response bodies

  Responses bodies are handled at two levels. When sending the request, a response body handler is specified. This is a function (`HttpResponse.BodyHandler`) which will be called with the response status code and headers, once these are received. This function is then expected to return a `HttpResponse.BodyProcessor` `<T>` which is then used to read the response body converting it into an instance of T. After this occurs, the response becomes available in a `HttpResponse` and `HttpResponse.body()` can then be called to obtain the body. Some implementations and examples of usage of both `HttpResponse.BodyProcessor` and `HttpResponse.BodyHandler` are provided in `HttpResponse`:

  Some of the pre-defined body handlers

  - `BodyHandler.asByteArray()` stores the body in a byte array
  - `BodyHandler.asString()` stores the body as a String
  - `BodyHandler.asFile(Path)` stores the body in a named file
  - `BodyHandler.discard()` discards the response body and returns the given value instead.

  Multi responses

  With HTTP/2 it is possible for a server to return a main response and zero or more additional responses (known as server pushes) to a client-initiated request. These are handled using a special response processor called `HttpResponse.MultiProcessor`.

  Blocking/asynchronous behavior and thread usage

  There are two styles of request sending: synchronous and asynchronous. `HttpClient.send(HttpRequest, HttpResponse.BodyHandler)` blocks the calling thread until the request has been sent and the response received.

  `HttpClient.sendAsync(HttpRequest, HttpResponse.BodyHandler)` is asynchronous and returns immediately with a `CompletableFuture`<`HttpResponse`> and when this object completes (in a background thread) the response has been received.

  `HttpClient.sendAsync(HttpRequest,HttpResponse.MultiProcessor)` is the variant for multi responses and is also asynchronous.

  `CompletableFuture`s can be combined in different ways to declare the dependencies among several asynchronous tasks, while allowing for the maximum level of parallelism to be utilized.

  Security checks

  If a security manager is present then security checks are performed by the sending methods. A `URLPermission` or `SocketPermission` is required to access any destination origin server and proxy server utilised. `URLPermission`s should be preferred in policy files over `SocketPermission`s given the more limited scope of `URLPermission`. Permission is always implicitly granted to a system's default proxies. The `URLPermission` form used to access proxies uses a method parameter of `"CONNECT"` (for all kinds of proxying) and a url string of the form `"socket://host:port"` where host and port specify the proxy's address.

  Examples

            HttpClient client = HttpClient
                    .newBuilder()
                    .build();

            HttpRequest request = HttpRequest
                    .newBuilder(new URI("http://www.foo.com/"))
                    .POST(BodyProcessor.fromString("Hello world"))
                    .build();

            HttpResponse<Path> response =
                client.send(request, BodyHandler.asFile(Paths.get("/path")));

            Path body = response.body();

  Asynchronous Example

  The above example will work asynchronously, if `(HttpRequest, HttpResponse.BodyHandler) sendAsync` is used instead of `send` in which case the returned object is a `CompletableFuture``<HttpResponse>` instead of `HttpResponse`. The following example shows how multiple requests can be sent asynchronously. It also shows how dependent asynchronous operations (receiving response, and receiving response body) can be chained easily using one of the many methods in `CompletableFuture`.

        // fetch a list of target URIs asynchronously and store them in Files.

            List<URI> targets = ...

            List<CompletableFuture<File>> futures = targets
                .stream()
                .map(target -> client
                        .sendAsync(
                            HttpRequest.newBuilder(target)
                                       .GET()
                                       .build(),
                            BodyHandler.asFile(Paths.get("base", target.getPath())))
                        .thenApply(response -> response.body())
                        .thenApply(path -> path.toFile()))
                .collect(Collectors.toList());

            // all async operations waited for here

            CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0]))
                .join();

            // all elements of futures have completed and can be examined.
            // Use File.exists() to check whether file was successfully downloaded

  Unless otherwise stated, `null` parameter values will cause methods of this class to throw `NullPointerException`.

  Since:
    9

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class | Description
    --- | --- | ---
    `static interface` | `HttpRequest.BodyProcessor` | A processor which converts high level Java objects into flows of `ByteBuffer`s suitable for sending as request bodies.
    `static class` | `HttpRequest.Builder` | A builder of `HttpRequest`s.

  - ### Constructor Summary

    Constructors
    Modifier | Constructor | Description
    --- | --- | ---
    `protected` | `HttpRequest​()` | Creates an HttpRequest.

  - ### Method Summary

    All Methods Static Methods Instance Methods Abstract Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `abstract Optional<HttpRequest.BodyProcessor>` | `bodyProcessor​()` | Returns an `Optional` containing the `HttpRequest.BodyProcessor` set on this request.
    `abstract Duration` | `duration​()` | Returns the duration for this request.
    `abstract boolean` | `expectContinue​()` | Returns this request's `expect continue` setting.
    `abstract HttpHeaders` | `headers​()` | The (user-accessible) request headers that this request was (or will be) sent with.
    `abstract String` | `method​()` | Returns the request method for this request.
    `static HttpRequest.Builder` | `newBuilder​()` | Creates a `HttpRequest` builder.
    `static HttpRequest.Builder` | `newBuilder​(URI uri)` | Creates a `HttpRequest` builder.
    `static HttpRequest.BodyProcessor` | `noBody​()` | A request body handler which sends no request body.
    `abstract URI` | `uri​()` | Returns this request's request `URI`.
    `abstract Optional<HttpClient.Version>` | `version​()` | Returns an `Optional` containing the HTTP protocol version that will be requested for this `HttpRequest`.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### HttpRequest

          protected HttpRequest​()

      Creates an HttpRequest.

  - ### Method Detail

    - #### newBuilder

          public static HttpRequest.Builder newBuilder​(URI uri)

      Creates a `HttpRequest` builder.
      Parameters:
        `uri` - the request URI
      Returns:
        a new request builder
      Throws:
        `IllegalArgumentException` - if the URI scheme is not supported.

    - #### newBuilder

          public static HttpRequest.Builder newBuilder​()

      Creates a `HttpRequest` builder.
      Returns:
        a new request builder

    - #### bodyProcessor

          public abstract Optional<HttpRequest.BodyProcessor> bodyProcessor​()

      Returns an `Optional` containing the `HttpRequest.BodyProcessor` set on this request. If no `BodyProcessor` was set in the requests's builder, then the `Optional` is empty.
      Returns:
        an `Optional` containing this request's `BodyProcessor`

    - #### method

          public abstract String method​()

      Returns the request method for this request. If not set explicitly, the default method for any request is "GET".
      Returns:
        this request's method

    - #### duration

          public abstract Duration duration​()

      Returns the duration for this request.
      Returns:
        this requests duration

    - #### expectContinue

          public abstract boolean expectContinue​()

      Returns this request's `expect continue` setting.
      Returns:
        this request's expect continue setting

    - #### uri

          public abstract URI uri​()

      Returns this request's request `URI`.
      Returns:
        this request's URI

    - #### version

          public abstract Optional<HttpClient.Version> version​()

      Returns an `Optional` containing the HTTP protocol version that will be requested for this `HttpRequest`. If the version was not set in the request's builder, then the `Optional` is empty. In that case, the version requested will be that of the sending `HttpClient`. The corresponding `HttpResponse` should be queried to determine the version that was actually used.
      Returns:
        HTTP protocol version

    - #### headers

          public abstract HttpHeaders headers​()

      The (user-accessible) request headers that this request was (or will be) sent with.
      Returns:
        this request's HttpHeaders

    - #### noBody

          public static HttpRequest.BodyProcessor noBody​()

      A request body handler which sends no request body.
      Returns:
        a BodyProcessor