Učinite jednostavan HTTP zahtjev na Javi

1. Pregled

U ovom kratkom vodiču predstavljamo način izvođenja HTTP zahtjeva u Javi - upotrebom ugrađene Java klase HttpUrlConnection.

Imajte na umu da, počevši od JDK 11, Java nudi novi API za izvođenje HTTP zahtjeva, koji je zamišljen kao zamjena za HttpUrlConnection, the HttpClient API.

2. HttpUrlConnection

The HttpUrlConnection razred nam omogućuje izvoditi osnovne HTTP zahtjeve bez upotrebe dodatnih knjižnica. Svi razredi koji su nam potrebni dio su java.net paket.

Mane primjene ove metode su sljedeće kôd može biti glomazniji od ostalih HTTP knjižnica i da ne pruža naprednije funkcionalnosti kao što su namjenske metode za dodavanje zaglavlja ili provjeru autentičnosti.

3. Izrada zahtjeva

Možemo stvoriti HttpUrlConnection primjer pomoću openConnection () metoda URL razred. Imajte na umu da ova metoda stvara samo objekt veze, ali još ne uspostavlja vezu.

The HttpUrlConnection klasa koristi se za sve vrste zahtjeva postavljanjem requestMethod atribut jednoj od vrijednosti: GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.

Stvorimo vezu s danim URL-om pomoću GET metode:

URL url = novi URL ("// example.com"); HttpURLConnection con = (HttpURLConnection) url.openConnection (); con.setRequestMethod ("GET");

4. Dodavanje parametara zahtjeva

Ako zahtjevu želimo dodati parametre, moramo postaviti doOutput svojstvo da pravi, a zatim napišite a Niz oblika param1 = vrijednost¶m2 = vrijednost prema Izlazni tok od HttpUrlConnection primjer:

Parametri karte = novi HashMap (); parameters.put ("param1", "val"); con.setDoOutput (true); DataOutputStream out = novi DataOutputStream (con.getOutputStream ()); out.writeBytes (ParameterStringBuilder.getParamsString (parametri)); out.flush (); out.close ();

Kako bi se olakšala transformacija parametarska karta, napisali smo klasu korisnosti nazvanu ParameterStringBuilder koji sadrže statičku metodu, getParamsString (), koji pretvara a Karta u a Niz potrebnog formata:

javna klasa ParameterStringBuilder {javni statički niz getParamsString (Map params) baca UnsupportedEncodingException {StringBuilder rezultat = novi StringBuilder (); for (Map.Entry entry: params.entrySet ()) {result.append (URLEncoder.encode (entry.getKey (), "UTF-8")); result.append ("="); result.append (URLEncoder.encode (entry.getValue (), "UTF-8")); result.append ("&"); } Niz rezultatString = rezultat.toString (); vratiti resultString.length ()> 0? resultString.substring (0, resultString.length () - 1): resultString; }}

5. Postavljanje zaglavlja zahtjeva

Dodavanje zaglavlja u zahtjev može se postići korištenjem setRequestProperty () metoda:

con.setRequestProperty ("Content-Type", "application / json");

Da bismo očitali vrijednost zaglavlja s veze, možemo koristiti getHeaderField () metoda:

Niz contentType = con.getHeaderField ("Tip sadržaja");

6. Konfiguriranje vremenskih ograničenja

HttpUrlConnection razred dopušta postavljanje vremena čekanja za povezivanje i čitanje. Te vrijednosti definiraju vremenski interval čekanja da se uspostavi veza s poslužiteljem ili podaci budu dostupni za čitanje.

Da bismo postavili vrijednosti vremenskog ograničenja, možemo koristiti setConnectTimeout () i setReadTimeout () metode:

con.setConnectTimeout (5000); con.setReadTimeout (5000);

U primjeru smo obje vrijednosti vremenskog ograničenja postavili na pet sekundi.

7. Rukovanje kolačićima

The java.net paket sadrži klase koje olakšavaju rad s kolačićima poput Upravitelj kolačića i HttpCookie.

Prvo, da pročitajte kolačiće iz odgovora, možemo dohvatiti vrijednost Set-kolačić zaglavlje i raščlanite ga na popis HttpCookie objekti:

String cookiesHeader = con.getHeaderField ("Set-Cookie"); Popis kolačića = HttpCookie.parse (cookiesHeader);

Dalje, hoćemo dodajte kolačiće u trgovinu kolačića:

cookies.forEach (cookie -> cookieManager.getCookieStore (). add (null, cookie));

Provjerimo je li nazvao kolačić Korisničko ime je prisutan, a ako ne, dodat ćemo ga u trgovinu kolačića s vrijednošću "john":

Izborno korisničko imeCookie = cookies.stream () .findAny (). Filter (cookie -> cookie.getName (). Jednako ("korisničko ime")); if (usernameCookie == null) {cookieManager.getCookieStore (). add (null, new HttpCookie ("username", "john")); }

Napokon, do dodajte kolačiće u zahtjev, moramo postaviti Kolačić zaglavlje, nakon zatvaranja i ponovnog otvaranja veze:

con.disconnect (); con = (HttpURLConnection) url.openConnection (); con.setRequestProperty ("Cookie", StringUtils.join (cookieManager.getCookieStore (). getCookies (), ";"));

8. Rukovanje preusmjeravanjima

Možemo omogućiti ili onemogućiti automatski nakon preusmjeravanja za određenu vezu pomoću setInstanceFollowRedirects () metoda sa pravi ili lažno parametar:

con.setInstanceFollowRedirects (netačno);

Također je moguće omogućiti ili onemogućiti automatsko preusmjeravanje za sve veze:

HttpUrlConnection.setFollowRedirects (netačno);

Prema zadanim postavkama ponašanje je omogućeno.

Kad zahtjev vraća statusni kod 301 ili 302, što ukazuje na preusmjeravanje, možemo dohvatiti Mjesto zaglavlje i stvorite novi zahtjev za novi URL:

if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM) {String location = con.getHeaderField ("Location"); URL newUrl = novi URL (mjesto); con = (HttpURLConnection) newUrl.openConnection (); }

9. Čitanje odgovora

Čitanje odgovora na zahtjev može izvršiti raščlanjivanje InputStream od HttpUrlConnection primjer.

Da bismo izvršili zahtjev, možemo koristiti getResponseCode (), Spojiti(), getInputStream () ili getOutputStream () metode:

int status = con.getResponseCode ();

Na kraju, pročitajmo odgovor na zahtjev i stavimo ga u sadržaj Niz:

BufferedReader u = novi BufferedReader (novi InputStreamReader (con.getInputStream ())); String inputLine; StringBuffer sadržaj = novi StringBuffer (); while ((inputLine = in.readLine ())! = null) {content.append (inputLine); } in.close ();

Do zatvorite vezu, možemo koristiti odspojiti () metoda:

con.disconnect (); 

10. Čitanje odgovora na neuspjele zahtjeve

Ako zahtjev ne uspije, pokušajte pročitati InputStream od HttpUrlConnection instanca neće raditi. Umjesto toga, možemo konzumirati tok koji pruža HttpUrlConnection.getErrorStream ().

Možemo odlučiti koji InputStream za upoređivanje HTTP statusnog koda:

int status = con.getResponseCode (); Čitač streamReader = null; if (status> 299) {streamReader = novi InputStreamReader (con.getErrorStream ()); } else {streamReader = novi InputStreamReader (con.getInputStream ()); }

I na kraju, možemo pročitati streamReader na isti način kao i prethodni odjeljak.

11. Izgradnja potpunog odgovora

Nije moguće dobiti prikaz punog odgovora pomoću HttpUrlConnection primjer.

Međutim, možemo ga izgraditi koristeći neke od metoda koje HttpUrlConnection instance nudi:

javna klasa FullResponseBuilder {javni statički niz getFullResponse (HttpURLConnection con) baca IOException {StringBuilder fullResponseBuilder = novi StringBuilder (); // čitanje statusa i poruke // čitanje zaglavlja // čitanje odgovora sadržaj povratak fullResponseBuilder.toString (); }}

Ovdje čitamo dijelove odgovora, uključujući statusni kod, statusnu poruku i zaglavlja, te ih dodajemo u StringBuilder primjer.

Prvo, dodajmo informacije o statusu odgovora:

fullResponseBuilder.append (con.getResponseCode ()) .append ("") .append (con.getResponseMessage ()) .append ("\ n");

Dalje ćemo koristiti zaglavlja getHeaderFields () i dodajte svakog od njih u naš StringBuilder u formatu HeaderName: Vrijednosti zaglavlja:

con.getHeaderFields (). entrySet (). stream () .filter (entry -> entry.getKey ()! = null) .forEach (entry -> {fullResponseBuilder.append (entry.getKey ()). append (": "); Popis headerValues ​​= entry.getValue (); Iterator it = headerValues.iterator (); if (it.hasNext ()) {fullResponseBuilder.append (it.next ()); while (it.hasNext ()) { fullResponseBuilder.append (",") .append (it.next ());}} fullResponseBuilder.append ("\ n");});

Na kraju ćemo pročitati sadržaj odgovora kao što smo to prethodno učinili i dodamo ga.

Imajte na umu da getFullResponse metoda provjerit će je li zahtjev bio uspješan ili ne kako bi se odlučilo treba li ga koristiti con.getInputStream () ili con.getErrorStream () za preuzimanje sadržaja zahtjeva.

12. Zaključak

U ovom smo članku pokazali kako možemo izvoditi HTTP zahtjeve pomoću HttpUrlConnection razred.

Potpuni izvorni kod primjera može se naći na GitHubu.