Gjør en enkel HTTP-forespørsel i Java

1. Oversikt

I denne raske opplæringen presenterer vi en måte å utføre HTTP-forespørsler på Java - ved å bruke den innebygde Java-klassen HttpUrlConnection.

Merk at startende med JDK 11, gir Java et nytt API for å utføre HTTP-forespørsler, som er ment som en erstatning for HttpUrlConnection, de HttpClient API.

2. HttpUrlConnection

De HttpUrlConnection klassen tillater oss å utføre grunnleggende HTTP-forespørsler uten bruk av ytterligere biblioteker. Alle klassene vi trenger er en del av java.net pakke.

Ulempene ved å bruke denne metoden er at koden kan være mer tungvint enn andre HTTP-biblioteker, og at den ikke gir mer avanserte funksjoner som dedikerte metoder for å legge til overskrifter eller autentisering.

3. Opprette en forespørsel

Vi kan lage en HttpUrlConnection eksempel bruker openConnection () metoden for URL klasse. Merk at denne metoden bare oppretter et tilkoblingsobjekt, men ikke oppretter tilkoblingen ennå.

De HttpUrlConnection klasse brukes til alle typer forespørsler ved å sette forespørselMetode attributt til en av verdiene: FÅ, POST, HODE, ALTERNATIVER, PUT, SLETT, SPOR.

La oss opprette en forbindelse til en gitt URL ved hjelp av GET-metoden:

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

4. Legge til forespørselsparametere

Hvis vi vil legge til parametere i en forespørsel, vi må stille inn doOutput eiendom til ekte, skriv deretter en String av skjemaet param1 = verdi¶m2 = verdi til OutputStream av HttpUrlConnection forekomst:

Kartparametere = nytt HashMap (); parameters.put ("param1", "val"); con.setDoOutput (true); DataOutputStream ut = ny DataOutputStream (con.getOutputStream ()); out.writeBytes (ParameterStringBuilder.getParamsString (parametere)); ut.flush (); ut. lukk ();

For å lette transformasjonen av parameter Kart, vi har skrevet en bruksklasse som heter ParameterStringBuilder inneholder en statisk metode, getParamsString (), som forvandler en Kart inn i en String av ønsket format:

offentlig klasse ParameterStringBuilder {public static String getParamsString (Map params) kaster UnsupportedEncodingException {StringBuilder result = new StringBuilder (); for (Map.Entry entry: params.entrySet ()) {result.append (URLEncoder.encode (entry.getKey (), "UTF-8")); resultat.append ("="); result.append (URLEncoder.encode (entry.getValue (), "UTF-8")); result.append ("&"); } Streng resultatString = resultat.tilString (); return resultString.length ()> 0? resultString.substring (0, resultString.length () - 1): resultString; }}

5. Angi forespørselsoverskrifter

Å legge til overskrifter i en forespørsel kan oppnås ved å bruke setRequestProperty () metode:

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

For å lese verdien av en topptekst fra en forbindelse, kan vi bruke getHeaderField () metode:

Streng contentType = con.getHeaderField ("Content-Type");

6. Konfigurere tidsavbrudd

HttpUrlConnection klasse tillater angi tidsavbrudd for tilkobling og lesing. Disse verdiene definerer tidsintervallet for å vente på at forbindelsen til serveren skal opprettes eller data skal være tilgjengelig for lesing.

For å stille tidsavbruddsverdiene kan vi bruke setConnectTimeout () og setReadTimeout () metoder:

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

I eksemplet setter vi begge tidsavbruddsverdiene til fem sekunder.

7. Håndtering av informasjonskapsler

De java.net pakken inneholder klasser som letter arbeidet med informasjonskapsler som CookieManager og HttpCookie.

Først til les informasjonskapslene fra et svar, kan vi hente verdien av Sett-informasjonskapsel topptekst og analyser den til en liste over HttpCookie gjenstander:

String cookiesHeader = con.getHeaderField ("Set-Cookie"); Liste informasjonskapsler = HttpCookie.parse (cookiesHeader);

Neste vil vi legg til informasjonskapslene i informasjonskapselbutikken:

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

La oss sjekke om en informasjonskapsel ringte brukernavn er til stede, og hvis ikke, vil vi legge det til informasjonskapselbutikken med verdien "john":

Valgfritt brukernavnCookie = cookies.stream () .findAny (). Filter (cookie -> cookie.getName (). Tilsvarer ("brukernavn")); hvis (brukernavnCookie == null) {cookieManager.getCookieStore (). legg til (null, ny HttpCookie ("brukernavn", "john")); }

Til slutt, til legg til informasjonskapslene i forespørselen, må vi stille inn Kjeks topptekst, etter å ha lukket og åpnet forbindelsen igjen:

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

8. Håndtering av viderekoblinger

Vi kan aktivere eller deaktivere automatisk etter viderekoblinger for en bestemt tilkobling ved å bruke setInstanceFollowRedirects () metode med ekte eller falsk parameter:

con.setInstanceFollowRedirects (false);

Det er også mulig å aktivere eller deaktivere automatisk omdirigering for alle tilkoblinger:

HttpUrlConnection.setFollowRedirects (false);

Som standard er atferden aktivert.

Når en forespørsel returnerer en statuskode 301 eller 302, som indikerer en viderekobling, kan vi hente plassering topptekst og opprette en ny forespørsel til den nye URL:

hvis (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM) {Stringplassering = con.getHeaderField ("Location"); URL newUrl = ny URL (plassering); con = (HttpURLConnection) newUrl.openConnection (); }

9. Lesing av svaret

Å lese svaret på forespørselen kan gjøres av analysere InputStream av HttpUrlConnection forekomst.

For å utføre forespørselen kan vi bruke getResponseCode (), koble(), getInputStream () eller getOutputStream () metoder:

int status = con.getResponseCode ();

Til slutt, la oss lese svaret på forespørselen og plassere den i et innhold Streng:

BufferedReader in = new BufferedReader (new InputStreamReader (con.getInputStream ())); Streng inputLine; StringBuffer innhold = nytt StringBuffer (); mens ((inputLine = in.readLine ())! = null) {content.append (inputLine); } in.close ();

Til lukk forbindelsen, kan vi bruke koble fra() metode:

koble fra (); 

10. Lese svaret på mislykkede forespørsler

Hvis forespørselen mislykkes, prøver du å lese InputStream av HttpUrlConnection forekomst vil ikke fungere. I stedet, vi kan konsumere strømmen som tilbys av HttpUrlConnection.getErrorStream ().

Vi kan bestemme hvilken InputStream å bruke ved å sammenligne HTTP-statuskoden:

int status = con.getResponseCode (); Reader streamReader = null; hvis (status> 299) {streamReader = ny InputStreamReader (con.getErrorStream ()); } annet {streamReader = ny InputStreamReader (con.getInputStream ()); }

Og til slutt kan vi lese streamReader på samme måte som forrige avsnitt.

11. Bygg full respons

Det er ikke mulig å få full responsrepresentasjon ved hjelp av HttpUrlConnection forekomst.

Derimot, vi kan bygge den ved hjelp av noen av metodene som HttpUrlConnection instans tilbud:

offentlig klasse FullResponseBuilder {offentlig statisk streng getFullResponse (HttpURLConnection con) kaster IOException {StringBuilder fullResponseBuilder = ny StringBuilder (); // lese status og melding // lese overskrifter // lese responsinnhold returnere fullResponseBuilder.toString (); }}

Her leser vi delene av svarene, inkludert statuskode, statusmelding og overskrifter, og legger disse til en StringBuilder forekomst.

La oss først legge til svarstatusinformasjonen:

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

Deretter får vi overskriftene getHeaderFields () og legg hver av dem til vår StringBuilder i formatet HeaderName: HeaderValues:

con.getHeaderFields (). entrySet (). stream () .filter (entry -> entry.getKey ()! = null) .forEach (entry -> {fullResponseBuilder.append (entry.getKey ()). append (": "); List 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");});

Til slutt vil vi lese svarinnholdet som vi gjorde tidligere, og legger det til.

Merk at getFullResponse metoden vil validere om forespørselen var vellykket eller ikke for å avgjøre om den må brukes con.getInputStream () eller con.getErrorStream () for å hente innholdet på forespørselen.

12. Konklusjon

I denne artikkelen viste vi hvordan vi kan utføre HTTP-forespørsler ved hjelp av HttpUrlConnection klasse.

Den fulle kildekoden til eksemplene finner du på GitHub.