- 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
instances are built fromHttpRequest
builders.HttpRequest
builders are obtained by callingHttpRequest.newBuilder
. A request's URI, headers and body can be set. Request bodies are provided through aHttpRequest.BodyPublisher
object supplied to theDELETE
,POST
orPUT
methods.GET
does not take a body. Once all required parameters have been set in the builder,HttpRequest.Builder.build()
is called to return theHttpRequest
. 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(BodyPublisher.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 aCompletableFuture
<HttpResponse
>.HttpClient.sendAsync(HttpRequest, HttpResponse.MultiSubscriber)
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 can be sent using one of the convenience request publisher implementations below, provided in
HttpRequest.BodyPublisher
. Alternatively, a custom Publisher 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 StringfromInputStream
(Supplier
<InputStream
>) from an InputStream obtained from a SupplierHttpRequest.BodyPublisher.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 they are received. This function is then expected to return a
HttpResponse.BodySubscriber
<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 aHttpResponse
, andHttpResponse.body()
can then be called to obtain the actual body. Some implementations and examples of usage of bothHttpResponse.BodySubscriber
andHttpResponse.BodyHandler
are provided inHttpResponse
:Some of the pre-defined body handlers
BodyHandler.asByteArray()
stores the body in a byte arrayBodyHandler.asString()
stores the body as a StringBodyHandler.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 subscriber called
HttpResponse.MultiSubscriber
.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 aCompletableFuture
<HttpResponse
> and when this object completes (possibly in a different thread) the response has been received.HttpClient.sendAsync(HttpRequest, HttpResponse.MultiSubscriber)
is the variant for multi responses and is also asynchronous.Instances of
CompletableFuture
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.If a security manager is present then security checks are performed by the HTTP Client's sending methods. An appropriate
URLPermission
is required to access the destination server, and proxy server if one has been configured. TheURLPermission
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.In this implementation, if an explicit executor has not been set for an
HttpClient
, and a security manager has been installed, then the default executor will execute asynchronous and dependent tasks in a context that is granted no permissions. Custom request body publishers, response body handlers, response body subscribers, and WebSocket Listeners, if executing operations that require privileges, should do so within an appropriate privileged context.Examples
HttpClient client = HttpClient .newBuilder() .build(); HttpRequest request = HttpRequest .newBuilder(new URI("http://www.foo.com/")) .POST(BodyPublisher.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 ofsend
in which case the returned object is aCompletableFuture
<HttpResponse>
instead ofHttpResponse
. 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 inCompletableFuture
.// 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 throwNullPointerException
.- Since:
- 9
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
HttpRequest.BodyPublisher
A Publisher which converts high level Java objects into flows of byte buffers suitable for sending as request bodies.static class
HttpRequest.Builder
A builder of HTTP Requests.
-
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.BodyPublisher>
bodyPublisher()
Returns anOptional
containing theHttpRequest.BodyPublisher
set on this request.boolean
equals(Object obj)
Tests this HTTP request instance for equality with the given object.abstract boolean
expectContinue()
Returns this request'sexpect continue
setting.int
hashCode()
Computes a hash code for this HTTP request instance.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 aHttpRequest
builder.static HttpRequest.Builder
newBuilder(URI uri)
Creates aHttpRequest
builder.abstract Optional<Duration>
timeout()
Returns anOptional
containing this request's timeout duration.abstract URI
uri()
Returns this request's requestURI
.abstract Optional<HttpClient.Version>
version()
Returns anOptional
containing the HTTP protocol version that will be requested for thisHttpRequest
.
-
-
-
Method Detail
-
newBuilder
public static HttpRequest.Builder newBuilder(URI uri)
Creates aHttpRequest
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 aHttpRequest
builder.- Returns:
- a new request builder
-
bodyPublisher
public abstract Optional<HttpRequest.BodyPublisher> bodyPublisher()
Returns anOptional
containing theHttpRequest.BodyPublisher
set on this request. If noBodyPublisher
was set in the requests's builder, then theOptional
is empty.- Returns:
- an
Optional
containing this request'sBodyPublisher
-
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
-
timeout
public abstract Optional<Duration> timeout()
Returns anOptional
containing this request's timeout duration. If the timeout duration was not set in the request's builder, then theOptional
is empty.- Returns:
- an
Optional
containing this request's timeout duration
-
expectContinue
public abstract boolean expectContinue()
Returns this request'sexpect continue
setting.- Returns:
- this request's expect continue setting
-
uri
public abstract URI uri()
Returns this request's requestURI
.- Returns:
- this request's URI
-
version
public abstract Optional<HttpClient.Version> version()
Returns anOptional
containing the HTTP protocol version that will be requested for thisHttpRequest
. If the version was not set in the request's builder, then theOptional
is empty. In that case, the version requested will be that of the sendingHttpClient
. The correspondingHttpResponse
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
-
equals
public final boolean equals(Object obj)
Tests this HTTP request instance for equality with the given object.If the given object is not an
HttpRequest
then this method returnsfalse
. Two HTTP requests are equal if their URI, method, and headers fields are all equal.This method satisfies the general contract of the
Object.equals
method.- Overrides:
equals
in classObject
- Parameters:
obj
- the object to which this object is to be compared- Returns:
true
if, and only if, the given object is anHttpRequest
that is equal to this HTTP request- See Also:
Object.hashCode()
,HashMap
-
hashCode
public final int hashCode()
Computes a hash code for this HTTP request instance.The hash code is based upon the HTTP request's URI, method, and header components, and satisfies the general contract of the
Object.hashCode
method.- Overrides:
hashCode
in classObject
- Returns:
- the hash-code value for this HTTP request
- See Also:
Object.equals(java.lang.Object)
,System.identityHashCode(java.lang.Object)
-
-