4.1 Metoda send(), BodyHandlers
Zakończyłeś naukę tworzenia żądania http , więc możesz przejść do najważniejszej rzeczy - wysłania tego żądania. W najprostszym przypadku jest to łatwe do zrobienia:
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() );
A jakie BodyHandlers
to są? Co myślisz? Wysłałeś zapytanie, co oznacza, że powinieneś otrzymać odpowiedź - http response
. A ta odpowiedź może mieć response body
: łańcuch, plik, tablicę bajtów, InputStream.
Tak, tak, zgadza się. Podobnie jak przy formułowaniu zapytania należy określić rodzaj response body
odpowiedzi. W sumie może być 8 sztuk:
BodyHandlers.ofByteArray
BodyHandlers.ofString
BodyHandlers.ofFile
BodyHandlers.discarding
BodyHandlers.replacing
BodyHandlers.ofLines
BodyHandlers.fromLineSubscriber
W zależności od tego, jaki typ BodyHandlers
przekazałeś metodzie send()
, zwróci ona taki typ wyniku. Przykład:
// 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());
Jeśli plik ma zostać wysłany do Ciebie jako odpowiedź, BodyHandlers.ofFile()
musisz przekazać do metody nazwę lokalnego pliku, w którym zostanie on zapisany przez obiekt HttpClient.
4.2 metoda followRedirects().
301
Ponadto, wysyłając żądanie, możesz określić, co HttpClient ma zrobić, jeśli serwer wyśle lub 302
(tymczasowe lub stałe przekierowanie) w odpowiedzi . Wyobraź sobie, że serwer wysłał kod 302
i musisz: prześledzić tę sytuację, uzyskać nowy adres URL z odpowiedzi i wysłać żądanie na nowy adres.
Nie bardzo chciałbym to zrobić, zwłaszcza biorąc pod uwagę, że taka sytuacja jest powszechna i od dawna jest zautomatyzowana we wszystkich klientach http. Również w tym HttpClient wystarczy określić, który tryb przekierowania wybierzesz podczas wysyłania żądania.
HttpResponse response = HttpClient.newBuilder()
.followRedirects( HttpClient.Redirect.ALWAYS )
.build()
.send(request, BodyHandlers.ofString());
Istnieją tylko 3 opcje przekierowania:
- ZAWSZE - zawsze;
- NIGDY - nigdy;
- NORMAL - zawsze, z wyjątkiem HTTPS -> HTTP.
Jak widać, nie ma tutaj wielu opcji, ale zawsze lepiej mieć możliwość dostosowania niż jej nie mieć.
4.4 Metoda proxy().
Istnieje kilka bardziej przydatnych, ale niezbyt często używanych opcji. Nie potrzebujesz ich dokładnie, dopóki ich nie potrzebujesz :)
Pierwszy to proxy. W zwykłym życiu nie często się z nimi spotykasz, ale wiele dużych korporacji ma w sobie złożony system bezpieczeństwa ruchu internetowego, a co za tym idzie różne ustawienia proxy.
Cóż, oczywiście twoje oprogramowanie, które będzie działać gdzieś w trzewiach takiej korporacji, kiedyś spotka się z faktem, że będzie musiało korzystać z proxy. Dlatego dobrze, że taka opcja jest również tutaj.
Konfiguracja proxy jest bardzo prosta - przykład:
HttpResponse<String> response = HttpClient.newBuilder()
.proxy( ProxySelector.getDefault())
.build()
.send(request, BodyHandlers.ofString());
Wybrano domyślne proxy, ale możesz chcieć ustawić własne:
HttpResponse response = HttpClient.newBuilder()
.proxy(ProxySelector.of(new InetSocketAddress("proxy.microsoft.com", 80)))
.build()
.send(request, BodyHandlers.ofString());
Nie będziemy rozważać, jak dokładnie pracować z pełnomocnikiem, ponieważ nie jest to objęte zakresem tego kursu.
4.5 uwierzytelniacz()
I jeszcze jeden ważny punkt. Protokół HTTP obsługuje uwierzytelnianie. Dokładnie na poziomie protokołu.
Teraz to podejście prawie nie jest używane, ale około 20 lat temu było powszechne. Żądanie HTTP wyglądało tak:
http://username@example.com/
Lub nawet tak:
http://username:password@example.com/
To nie jest poczta. To jest dokładnie ten link. I tak, nie myślałeś tak. Login, a nawet hasło można określić bezpośrednio w żądaniu http. Tak, nawet teraz możesz. Dlatego piszę, że teraz zwykle nikt tego nie robi. Ale jest taka możliwość.
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());
To jest interesujące! Czy wiesz, dlaczego zamiast “password"
w kodzie jest napisane "password".toCharArray()
?
Ponieważ drugim parametrem konstruktora PasswordAuthentication
nie jest String
, ale CharArray
.
A dlaczego drugi parametr nie jest String
, huh CharArray
?
Ponieważ wszystkie hasła nie mogą być przechowywane jako cały ciąg ze względów bezpieczeństwa, nawet we własnej aplikacji . Oznacza to, że Twoja aplikacja w swojej pamięci nie powinna przechowywać hasła jako ciągu znaków. Żeby jak ktoś zrobił wilgotną pamięć to hasła nie dało się z niej wyciągnąć...
Ale jednocześnie hasło może być przesyłane przez niezabezpieczony protokół HTTP na pół świata :) :) :)
Dobrze. Świat nie jest doskonały.
Więcej na ten temat można przeczytać pod poniższymi linkami: