4.1 The send() method, BodyHandlers
You have finished learning how to form an http request , so you can move on to the most important thing - sending this request. In the simplest case, this is easy to do:
HttpRequest request = HttpRequest.newBuilder(new URI("https://codegym.cc")).build();
HttpClient client = HttpClient.newBuilder()
.version(Version.HTTP_1_1)
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode() );
System.out.println(response.body() );
And what are BodyHandlers
these? What do you think? You sent a request, which means you should receive an answer - http response
. And this response can have response body
: a string, a file, an array of bytes, an InputStream.
Yes, yes, that's right. Just like when forming a request, you need to specify the type response body
of the response. There can be 8 pieces in total:
BodyHandlers.ofByteArray
BodyHandlers.ofString
BodyHandlers.ofFile
BodyHandlers.discarding
BodyHandlers.replacing
BodyHandlers.ofLines
BodyHandlers.fromLineSubscriber
Depending on what type BodyHandlers
you passed to the method send()
, it will return such a result type. Example:
// response body is ignored
HttpResponse<Void> response = client.send(request, BodyHandlers.discarding());
// response body is a string
HttpResponse<String>response = client.send(request, BodyHandlers.ofString());
// response body is a file
HttpResponse<Path> response = client.send(request, BodyHandlers.ofFile(Paths.get("readme.txt")));
// response body is an InputStream
HttpResponse<InputStream> response = client.send(request, BodyHandlers.ofInputStream());
If a file should be sent to you as a response, then BodyHandlers.ofFile()
you need to pass the name of the local file to the method, where it will be saved by the HttpClient object.
4.2 followRedirects() method
301
Also, when sending a request, you can specify what HttpClient should do if the server sends or 302
(temporary or permanent redirect) in response . Imagine that the server has sent a code 302
, and you need to: track this situation, get a new URL from the response, and send the request to the new address.
I would not much like to do this, especially considering that this situation is common and has long been automated in all http clients. Also in this HttpClient you just need to specify which redirect mode you choose when sending the request.
HttpResponse response = HttpClient.newBuilder()
.followRedirects( HttpClient.Redirect.ALWAYS )
.build()
.send(request, BodyHandlers.ofString());
There are only 3 options for a redirect:
- ALWAYS - always;
- NEVER - never;
- NORMAL - always, except HTTPS -> HTTP.
As you can see, there are not many options here, but it is always better to have the ability to customize than not to have it.
4.4 The proxy() method
There are a couple more useful, but not often used options. You don't need them exactly until you need them :)
The first one is proxy. In ordinary life, you do not often encounter them, but many large corporations have a complex Internet traffic security system inside them, and hence various proxy settings.
Well, of course, your software, which will work somewhere in the bowels of such a corporation, will someday encounter the fact that it will need to use a proxy. Therefore, it is good that such an option is also here.
Setting up a proxy is very simple - an example:
HttpResponse<String> response = HttpClient.newBuilder()
.proxy( ProxySelector.getDefault())
.build()
.send(request, BodyHandlers.ofString());
The default proxy has been chosen here, but you may want to set your own:
HttpResponse response = HttpClient.newBuilder()
.proxy(ProxySelector.of(new InetSocketAddress("proxy.microsoft.com", 80)))
.build()
.send(request, BodyHandlers.ofString());
How exactly to work with a proxy, we will not consider, since this is not included in the scope of this course.
4.5 authenticator()
And one more important point. The HTTP protocol supports authentication. Right at the protocol level.
Now this approach is almost not used, but about 20 years ago it was common. The Http request looked like this:
http://username@example.com/
Or even like this:
http://username:password@example.com/
This is not mail. This is exactly the link. And yes, you didn't think so. The login and even the password could be specified directly in the http request. Yes, even now you can. That's why I write that no one usually does this now. But there is such a possibility.
Authenticator auth = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
"username",
"password".toCharArray());
}
};
HttpResponse<String> response = HttpClient.newBuilder()
.authenticator(auth).build()
.send(request, BodyHandlers.ofString());
This is interesting! Do you know why instead of “password"
in the code it says "password".toCharArray()
?
Because the second parameter of the constructor PasswordAuthentication
is not String
, but CharArray
.
And why the second parameter is not String
, huh CharArray
?
Because all passwords are not allowed to be stored as a whole string for security purposes, even in your own application . That is, your application in its memory should not store the password as a string. So that if someone made damp-memory, the password could not be pulled out of it ...
But at the same time, the password can be transmitted over an insecure HTTP protocol across half the world :) :) :)
Well. The world is not perfect.
You can read more about this topic at the links below: