In Java 11, the HTTP Client API is standardized. The new API supports both HTTP/ 1.1 and HTTP/ 2. It is designed in such a way that it improves the overall send-to-customer performance and receives responses from the server. Cheap documents are also supported.
The Java 11 HTTP client is part of the Java SE platform and has the following classes and interfaces that reside in the java.net.http
package (module: java.net.http
).
java.net.HttpClient class:
To send requests, first, you have to create a HttpClient
builder-style API. You can edit the settings for each client when choosing a client. Once done, the HttpClient
instance does not change, so it is automatically secure, and you can send multiple requests with it.
By default, the client tries to open the HTTP/2 connection, when the server responds with HTTP/1.1, the client automatically falls into this version. Here is a video to explain the difference between HTTP 1.1 and HTTP 2.
If you know in advance that the server only communicates with HTTP/1.1, you can create the client with the version (Version.HTTP_1_1
).
The ConnectTimeout()
determines how long the client waits until the connection can be established. If the connection cannot be established, the client throws an exception. If you do not specify an executor, a default forum is created for each newly created HttpClient
. The default installer uses a string pool.
A Client can be built in two ways namely, default and custom clients
Have a look at this example:
/* creating a default client */
var dClient = HttpClient.newHttpClient();
/* creating a custom client */
var cClient = HttpClient.newBuilder()
.followRedirects(Redirect.Default)
.authenticator(Authenticator.getDefault())
.connectTimeout(Duration.ofSeconds(50))
.priority(1)
.version(HttpClient.Version.HTTP_1)
.build();
The HttpClient.Builder
contains methods such as:
-
authenticator(Authenticator auth)
which is used to authenticate HTTP.
-
connectTimeout(Duration duration)
sets the connection time for the client.
-
cookieHandler(cookieHandler cookieHandler)
sets the cookies.
-
followRedirects(HttpClient.Redirect policy)
checks the automatic flow of requests issued by the server.
-
proxy(ProxySelector proxySelector)
– used to set a ProxySelector
selects which proxy server to use.
-
sslContext?(SSLContext sslContext)
– for setting the SSLContext
-
version(HTTPClient.Version version)
– to request a specific HTTP protocol version.
java.net.HttpRequest
The same thing is done to clients, building HttpRequest instances with the builder. You must set a URI, request method, and specify your body, time, and title.
HttpRequest
instances are unchanged and can be sent multiple times.
The request URI can be specified via Uri ()
or as a NewBuilder ()
argument. There is no difference in performance.
timeout ()
uses the timeout only for this request. If the client gets no response for a fixed amount of time, throws HttpTimeoutException
out, then SendAsync ()
uniquely completes this exception. If you do not set a timeout, the client waits permanently.
java.net.HttpResponse
HttpResponse
is an interface and is not directly built. The use of this connection is refunded by the customer upon submission of the request.
It is taken as:
HttpResponse<String> response = client.send(req, BodyHandlers.ofString());
Another way is:
HttpResponse<?> response1 = HttpClient.newHttpClient()
.send(req, BodyHandlers.discarding());
HttpResponse<?> response1 = HttpClient.newHttpClient()
.send(req, BodyHandlers.replacing(value));
Let us have a look at a few of the methods provided in the response interface.
Method |
Function |
T body() |
returns the body of the reaction |
HttpHeaders headers() |
returns the response headers |
HttpRequest request() |
returns the HttpRequest associated with this response |
int StatusCode() |
Returns the HTTP status code |
URI uri() |
returns the URI for the response to be received from |
HttpClient.Version version() |
Returns the HTTP protocol |
Hence the above methods can be summed up with an example through HTTP GET
request:
HttpClient httpClient = HttpClient.newBuilder().build();
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8080/hello"))
.build();
HttpResponse<String> response;
try
{
response = httpClient.send(req, BodyHandlers.ofString());
System.out.println(response.body());
}
catch (IOException e)
{
e.printStackTrace();
}
Though HTTP POST
Request:
HttpRequest mainRequest = HttpRequest.newBuilder().POST(BodyPublishers.ofString("Send me!"))
.header("Content-Type", "text/plain")
.uri(URI.create("http://localhost:8080/postIt"))
.build();
try {
httpClient.send(mainRequest, BodyHandlers.ofString());
} catch (IOException e) {
e.printStackTrace();
}
HttpRequest.BodyPublisher
Using Bodypublisher is viewed when submitting a request through the body of an application. BodyPublisher converts objects into a stream of Byte buffers that are ready to be sent as a body.
Syntax:
fromPublisher(Flow.Publisher<? extends ByteBuffer> publisher)
fromPublisher?(Flow.Publisher<? extends ByteBuffer> publisher, long contentLength)
HttpRequest.BodyPublishers
A BodyPublisher implementation uses various useful publishing, such as publishing an application body in String, or on file.
BodyPublishers::ofString
BodyPublishers::ofFile
HttpResponse.BodyHandler
- BodyHandlers is responsible for converting bytes from a response into high-quality Java formats, such as String or Path.
- This interaction allows checking the status code and headers before the actual response body is detected.
HttpResponse.BodyHandlers
- The factory section that provides the BodyHandler implementation for handling standard body types for a response such as files, cables, and bytes.
- This function does not check the status code.
- Usually, they return HttpResponse.BodySubscript with the same name
Examples for the same are mentioned in the above codes.
WebSocket
The Java 11 HTTP client not only supports HTTP but also includes a WebSocket client.
WebSocket is a protocol that enables the communication between the server and the browser. It is more advantageous than RESTful HTTP because communication is both direct and real-time. This allows the server to notify the client at any time instead of customer voting at regular check-out.
public class WebSocket
{
public static void main(String[] args) throws IOException, NoSuchAlgorithmException
{
ServerSocket server = new ServerSocket(80);
try
{
System.out.println("Server has started on 127.0.0.1:80.\r\nWaiting for a connection...");
Socket client = server.accept();
System.out.println("A client connected.");
InputStream in = client.getInputStream();
OutputStream out = client.getOutputStream();
Scanner s = new Scanner(in, "Mohit");
try
{
String data = s.useDelimiter("\\r\\n\\r\\n").next();
Matcher get = Pattern.compile("^GET").matcher(data);
if (get.find())
{
Matcher match = Pattern.compile("Sec-WebSocket-Key: (.*)").matcher(data);
match.find();
byte[] response = ("HTTP/1.2 102 Switching Protocols\r\n"
+ "Connection: Upgrade\r\n"
+ "Upgrade: websocket\r\n"
+ "Sec-WebSocket-Accept: "
+ Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-1").digest((match.group(1) + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").getBytes("UTF-8")))
+ "\r\n\r\n").getBytes("UTF-8");
out.write(response, 0, response.length);
byte[] decoded = new byte[6];
byte[] encoded = new byte[] { (byte) 198, (byte) 131, (byte) 130, (byte) 182, (byte) 194, (byte) 135 };
byte[] key = new byte[] { (byte) 167, (byte) 225, (byte) 225, (byte) 210 };
for (int i = 0; i < encoded.length; i++) {
decoded[i] = (byte) (encoded[i] ^ key[i & 0x3]);
}
}
}
finally
{
s.close();
}
}
finally
{
server.close();
}
}
}
Conclusion:
With this, we have covered the new HTTP Clients introduced in Java 11.
If we missed any important heading under this topic, please do share it with us in the comment section.