Studiuję aplikację stworzoną przez naszą firmę. Używa biblioteki Apache HttpClient. W kodzie źródłowym wykorzystuje HttpClient
klasę do tworzenia instancji do łączenia się z serwerem.
Chcę dowiedzieć się więcej o Apache HttpClient i przejrzałem ten zestaw przykładów . Wszystkie przykłady używają CloseableHttpClient
zamiast HttpClient
. Myślę więc, że CloseableHttpClient
jest to rozszerzona wersja HttpClient
. Jeśli tak jest, mam dwa pytania:
- Jaka jest różnica między tymi dwoma?
- Która klasa jest zalecana do mojego nowego rozwoju?
java
apache
http
apache-httpclient-4.x
Nayana Adassuriya
źródło
źródło
HttpClient
instancji? Jeśli jest to ważne, dlaczegoclose()
metoda nie jest częścią podstawowego interfejsu?Odpowiedzi:
Oto przykład procesu realizacji żądania w jego najprostszej formie:
Cofnięcie alokacji zasobów HttpClient: gdy wystąpienie CloseableHttpClient nie jest już potrzebne i ma wyjść poza zakres, skojarzony z nim menedżer połączeń musi zostać zamknięty, wywołując metodę CloseableHttpClient # close ().
zobacz dokumentację, aby poznać podstawy.
@Scadge Od wersji Java 7 użycie instrukcji try-with-resources zapewnia, że każdy zasób jest zamknięty na końcu instrukcji. Może być używany zarówno dla klienta, jak i dla każdej odpowiedzi
try(CloseableHttpClient httpclient = HttpClients.createDefault()){ // e.g. do this many times try (CloseableHttpResponse response = httpclient.execute(httpget)) { //do something } //do something else with httpclient here }
źródło
httpget
również zamknąćMiałem to samo pytanie. Inne odpowiedzi nie wydają się odpowiadać, dlaczego metoda close () jest naprawdę konieczna? Wydawało się również, że Op ma problem ze znalezieniem preferowanego sposobu pracy z HttpClient i in.
Według Apache :
// The underlying HTTP connection is still held by the response object // to allow the response content to be streamed directly from the network socket. // In order to ensure correct deallocation of system resources // the user MUST call CloseableHttpResponse#close() from a finally clause.
Ponadto relacje wyglądają następująco:
Preferowany sposób według Apache:
Przykład dają robi
httpclient.close()
wfinally
klauzuli, a także posługuje sięResponseHandler
również.Alternatywnie sposób, w jaki robi to mkyong, jest również nieco interesujący:
Nie pokazuje
client.close()
połączenia, ale myślę, że jest to konieczne, ponieważclient
nadal jest przykłademCloseableHttpClient
.źródło
Inne odpowiedzi wydają się nie wyjaśniać, dlaczego
close()
jest to naprawdę konieczne? * 2Wątpliwości dotyczące odpowiedzi „Cofnięcie alokacji zasobów HttpClient”.
Jest wspomniany w starym dokumencie httpcomponents 3.x , który jest dawno temu i różni się znacznie od HC 4.x. Poza tym wyjaśnienie jest tak krótkie, że nie mówi, czym jest ten podstawowy zasób.
Zrobiłem trochę badań nad kodem źródłowym wydania 4.5.2, stwierdziłem, że implementacje w
CloseableHttpClient:close()
zasadzie tylko zamyka jego menedżera połączeń.(FYI) Dlatego, gdy używasz współdzielonego
PoolingClientConnectionManager
i wywołującego klientaclose()
,java.lang.IllegalStateException: Connection pool shut down
wystąpi wyjątek . Aby tego uniknąć,setConnectionManagerShared
działa.Wolę nie robić
CloseableHttpClient:close()
po każdej prośbieKiedyś tworzyłem nową instancję klienta http podczas wykonywania żądania i ostatecznie ją zamykałem. W takim przypadku lepiej nie dzwonić
close()
. Ponieważ, jeśli menedżer połączeń nie ma flagi „udostępniony”, zostanie zamknięty, co jest zbyt kosztowne dla pojedynczego żądania.W rzeczywistości znalazłem również w bibliotece clj-http , opakowanie Clojure nad Apache HC 4.5, w ogóle nie wywołuje
close()
. Zobacz funcrequest
w pliku core.cljźródło
W kolejnej większej wersji
HttpClient
interfejs biblioteki ma zostać rozszerzonyCloseable
. Do tego czasu zalecane jest używanie,CloseableHttpClient
jeśli nie jest wymagana zgodność z wcześniejszymi wersjami 4.x (4.0, 4.1 i 4.2).źródło
HttpClient
to nie klasa, to interfejs. Nie możesz go wykorzystać do rozwoju w sposób, jaki masz na myśli.To, czego chcesz, to klasa, która implementuje
HttpClient
interfejs, i to jestCloseableHttpClient
.źródło
CloseableHttpClient
jest podstawową klasą biblioteki httpclient, której używają wszystkie implementacje. Inne podklasy są w większości przestarzałe.HttpClient
Jest interfejsem dla tej klasy i innych klas.Następnie należy użyć
CloseableHttpClient
w swoim kodzie i utworzyć go przy użyciuHttpClientBuilder
. Jeśli chcesz opakować klienta w celu dodania określonego zachowania, powinieneś użyć przechwytywaczy żądań i odpowiedzi zamiast zawijania za pomocąHttpClient
.Ta odpowiedź została udzielona w kontekście httpclient-4.3.
źródło
Jon Skeet powiedział:
Dokumentacja wydaje mi się całkiem jasna: „Podstawowa implementacja HttpClient, która również implementuje Closeable” - HttpClient to interfejs; CloseableHttpClient jest klasą abstrakcyjną, ale ponieważ implementuje AutoCloseable, można jej użyć w instrukcji try-with-resources.
Ale potem Jules zapytał:
@JonSkeet To jasne, ale jak ważne jest zamykanie instancji HttpClient? Jeśli to ważne, dlaczego metoda close () nie jest częścią podstawowego interfejsu?
Odpowiedź dla Julesa
Aby uwzględnić instrukcję try-with-resources. Wdrożenie Zamknięcie jest obowiązkowe. Dlatego uwzględniono go w CloseableHttpClient .
Uwaga:
close metoda w AbstractHttpClient, która rozszerza CloseableHttpClient, jest przestarzała, nie mogłem znaleźć kodu źródłowego do tego.
źródło