public abstract class HttpRequest extends Object
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 arrayfromByteArrays(Iterable)
from an Iterable of byte arraysfromFile(Path)
from the file located
at the given PathfromString(String)
from a String fromInputStream
(Supplier
<
InputStream
>) from an InputStream obtained from a SuppliernoBody()
no request body is sentResponse 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 arrayBodyHandler.asString()
stores the body as a String BodyHandler.asFile(Path)
stores the body in a named fileBodyHandler.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
.
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. |
Modifier | Constructor | Description |
---|---|---|
protected |
HttpRequest() |
Creates an HttpRequest.
|
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 HttpClient.Version |
version() |
Returns the HTTP protocol version that will be requested for this
HttpRequest . |
public static HttpRequest.Builder newBuilder(URI uri)
HttpRequest
builder.uri
- the request URIIllegalArgumentException
- if the URI scheme is not supported.public static HttpRequest.Builder newBuilder()
HttpRequest
builder.public abstract Optional<HttpRequest.BodyProcessor> bodyProcessor()
Optional
containing the HttpRequest.BodyProcessor
set on this request. If no BodyProcessor
was set in the
requests's builder, then the Optional
is empty.Optional
containing this request's
BodyProcessor
public abstract String method()
public abstract Duration duration()
public abstract boolean expectContinue()
expect continue
setting.public abstract URI uri()
URI
.public abstract HttpClient.Version version()
HttpRequest
. The corresponding HttpResponse
should be
queried to determine the version that was actually used.public abstract HttpHeaders headers()
public static HttpRequest.BodyProcessor noBody()
Submit a bug or feature
Java is a trademark or registered trademark of Oracle and/or its affiliates in the US and other countries.
Copyright © 2015, 2017, Oracle and/or its affiliates. 500 Oracle Parkway
Redwood Shores, CA 94065 USA. All rights reserved.
DRAFT 9-Debian+0-9b155-1