HTTP-forespørsler med Kotlin og khttp

1. Introduksjon

HTTP-protokollen og API-er bygget på den er av sentral betydning i programmeringen i disse dager.

På JVM har vi flere tilgjengelige alternativer, fra lavere nivå til veldig høyt nivå biblioteker, fra etablerte prosjekter til nye barn på blokken. Imidlertid er de fleste av dem hovedsakelig rettet mot Java-programmer.

I denne artikkelen, vi skal se på khttp, et idiomatisk Kotlin-bibliotek for å konsumere HTTP-baserte ressurser og API-er.

2. Avhengigheter

For å kunne bruke biblioteket i prosjektet vårt, må vi først legge det til våre avhengigheter:

 khttp khttp 0.1.0 

Siden dette ennå ikke er på Maven Central, må vi også aktivere JCenter-arkivet:

 sentrale //jcenter.bintray.com 

Versjon 0.1.0 er den nåværende i skrivende stund. Vi kan selvfølgelig sjekke JCenter for en nyere.

3. Grunnleggende bruk

Grunnleggende om HTTP-protokollen er enkle, selv om de fine detaljene kan være ganske kompliserte. Derfor har khttp også et enkelt grensesnitt.

For hver HTTP-metode kan vi finne en funksjon på pakkenivå i khttp pakke, som for eksempel få, post og så videre.

Funksjonene tar alle det samme settet med argumenter og returnerer a Respons gjenstand; vi får se detaljene i disse avsnittene nedenfor.

I løpet av denne artikkelen bruker vi det fullstendige skjemaet, for eksempel khttp.put. I våre prosjekter kan vi selvfølgelig importere og muligens gi nytt navn til disse metodene:

importer khttp.delete som httpDelete

Merk: Vi har lagt til typedeklarasjoner for klarhet gjennom kodeeksemplene fordi uten IDE kan de være vanskelig å følge.

4. En enkel forespørsel

Hver HTTP-forespørsel har minst to nødvendige komponenter: en metode og en URL. I khttp bestemmes metoden av funksjonen vi påberoper, som vi har sett i forrige avsnitt.

URL-en er det eneste nødvendige argumentet for metoden; så vi kan enkelt utføre en enkel forespørsel:

khttp.get ("// httpbin.org/get")

I de følgende avsnittene vil vi vurdere alle forespørsler om å fullføre.

4.1. Legge til parametere

Vi må ofte oppgi spørsmålsparametere i tillegg til basis-URL, spesielt for GET-forespørsler.

khttps metoder godtar a params argument hvilken er en Kart av nøkkelverdipar som skal inkluderes i spørringen Streng:

khttp.get (url = "//httpbin.org/get", params = mapOf ("key1" til "value1", "keyn" til "valuen"))

Legg merke til at vi har brukt mapOf funksjon for å konstruere en Kart i farta; den resulterende forespørsel-URL vil være:

//httpbin.org/get?key1=value1&keyn=valuen

5. En anmodningsinstans

En annen vanlig operasjon vi ofte trenger å utføre er å sende data, vanligvis som nyttelasten til en POST- eller PUT-forespørsel.

For dette tilbyr biblioteket flere alternativer som vi skal undersøke i de følgende avsnittene.

5.1. Sende en JSON-nyttelast

Vi kan bruke json argument for å sende et JSON-objekt eller en matrise. Det kan være av flere forskjellige typer:

  • EN JSONObject eller JSONArray som levert av org.json-biblioteket
  • EN Kart, som blir forvandlet til et JSON-objekt
  • EN Samling, Iterabel eller array, som er transformert til en JSON-array

Vi kan enkelt gjøre vårt tidligere GET-eksempel om til en POST som sender et enkelt JSON-objekt:

khttp.post (url = "//httpbin.org/post", json = mapOf ("key1" til "value1", "keyn" til "valuen"))

Merk at transformasjonen fra samlinger til JSON-objekter er grunne. For eksempel, a Liste av Kart‘S blir ikke konvertert til et JSON-utvalg av JSON-objekter, men snarere til et utvalg av strenger.

For dyp konvertering trenger vi et mer komplekst JSON-kartleggingsbibliotek som Jackson. Konverteringsanlegget til biblioteket er kun ment for enkle saker.

5.2. Sende skjemadata (URL-kodet)

For å sende skjemadata (URL-kodet, som i HTML-skjemaer) bruker vi data argument med en Kart:

khttp.post (url = "//httpbin.org/post", data = mapOf ("key1" til "value1", "keyn" til "valuen"))

5.3. Laste opp filer (flerdelt skjema)

Vi kan sende en eller flere filer kodet som en forespørsel om skjema med flere deler.

I så fall bruker vi filer argument:

khttp.post (url = "//httpbin.org/post", files = listOf (FileLike ("file1", "content1"), FileLike ("file2", File ("kitty.jpg"))))

Vi kan se at khttp bruker a FileLike abstraksjon, som er et objekt med navn og innhold. Innholdet kan være en streng, en byteoppstilling, en Fil, eller a Sti.

5.4. Sender råinnhold

Hvis ingen av alternativene ovenfor er passende, kan vi bruke en InputStream å sende rådata som kroppen til en HTTP-forespørsel:

khttp.post (url = "//httpbin.org/post", data = someInputStream)

I dette tilfellet trenger vi mest sannsynlig å sette noen overskrifter manuelt også, som vi vil dekke i en senere del.

6. Håndtering av responsen

Så langt har vi sett forskjellige måter å sende data til en server på. Men mange HTTP-operasjoner er nyttige på grunn av dataene de også returnerer.

khttp er derfor basert på å blokkere I / O alle funksjoner som tilsvarer HTTP-metoder returnerer a Respons gjenstand som inneholder svaret du mottok fra serveren.

Dette objektet har forskjellige egenskaper som vi kan få tilgang til, avhengig av typen innhold.

6.1. JSON-svar

Hvis vi vet svaret til å være et JSON-objekt eller en matrise, kan vi bruke jsonObject og jsonArray eiendommer:

val respons: Response = khttp.get ("// httpbin.org/get") val obj: JSONObject = response.jsonObject print (obj ["someProperty"])

6.2. Tekst eller binære svar

Hvis vi vil lese svaret som en String i stedet kan vi bruke tekst eiendom:

val-melding: String = respons.text

Eller hvis vi vil lese det som binære data (f.eks. En filnedlasting) bruker vi innhold eiendom:

val imageData: ByteArray = respons.innhold

Endelig kan vi også få tilgang til det underliggende InputStream:

val inputStream: InputStream = respons.raw

7. Avansert bruk

La oss også se på et par mer avanserte bruksmønstre som generelt er nyttige, og som vi ennå ikke har behandlet i de forrige avsnittene.

7.1. Håndtering av overskrifter og informasjonskapsler

Alle khttp-funksjoner tar en topptekster argument hvilken er en Kart av overskriftsnavn og verdier.

val respons = khttp.get (url = "//httpbin.org/get", headers = mapOf ("header1" to "1", "header2" to "2"))

Tilsvarende for informasjonskapsler:

val respons = khttp.get (url = "//httpbin.org/get", cookies = mapOf ("cookie1" til "1", "cookie2" til "2"))

Vi har også tilgang til overskrifter og informasjonskapsler sendt av serveren i svaret:

val contentType: String = response.headers ["Content-Type"] val sessionID: String = response.cookies ["JSESSIONID"]

7.2. Håndteringsfeil

Det er to typer feil som kan oppstå i HTTP: feilresponser, for eksempel 404 - Not Found, som er en del av protokollen; og feil på lavt nivå, for eksempel “tilkobling nektet”.

Den første typen resulterer ikke i khttp-kaste unntak; i stedet, vi bør sjekke SvarstatusKode eiendom:

val respons = khttp.get (url = "//httpbin.org/nothing/to/see/here") hvis (respons.statusCode == 200) {prosess (respons)} annet {handleError (respons)}

Feil på lavere nivå resulterer i stedet i at unntak kastes fra det underliggende Java I / O-delsystemet, for eksempel ConnectException.

7.3. Streaming-svar

Noen ganger kan serveren svare med et stort innhold, og / eller ta lang tid å svare. I slike tilfeller vil vi kanskje behandle responsen i biter, i stedet for å vente på at den skal fullføres og ta opp minne.

Hvis vi vil instruere biblioteket om å gi oss en streaming-respons, må vi passere ekte som strøm argument:

val respons = khttp.get (url = "//httpbin.org", stream = true)

Deretter kan vi behandle det i biter:

response.contentIterator (chunkSize = 1024) .forEach {arr: ByteArray -> handleChunk (arr)}

7.4. Ikke-standardiserte metoder

I det usannsynlige tilfellet at vi trenger å bruke en HTTP-metode (eller verb) som khttp ikke gir naturlig - si, for en eller annen utvidelse av HTTP-protokollen, som WebDAV - er vi fortsatt dekket.

Faktisk er alle funksjonene i khttp-pakken, som tilsvarer HTTP-metoder, implementert ved hjelp av en generisk be om funksjon som vi også kan bruke:

khttp.request (method = "COPY", url = "//httpbin.org/get", headers = mapOf ("Destination" to "/ copy-of-get"))

7.5. Andre funksjoner

Vi har ikke rørt alle funksjonene i khttp. For eksempel har vi ikke diskutert tidsavbrudd, viderekoblinger og historikk eller asynkrone operasjoner.

Den offisielle dokumentasjonen er den ultimate informasjonskilden om biblioteket og alle dets funksjoner.

8. Konklusjon

I denne opplæringen har vi sett hvordan du kan lage HTTP-forespørsler i Kotlin med det idiomatiske biblioteket khttp.

Implementeringen av alle disse eksemplene finnes i GitHub-prosjektet.


$config[zx-auto] not found$config[zx-overlay] not found