Erstellen Sie eine HTTP-Anfrage in Kotlin

David Mbochi Njonge 20 Juni 2023
  1. Erstellen Sie ein Kotlin-Projekt und fügen Sie Abhängigkeiten hinzu
  2. Verwenden Sie Retrofit, um eine HTTP-Anforderung in Kotlin zu erstellen
  3. Verwenden Sie eine API der Java-Standardbibliothek, um eine HTTP-Anforderung in Kotlin zu erstellen
  4. Verwenden Sie die Fuel-API, um eine HTTP-Anforderung in Kotlin zu erstellen
  5. Verwenden Sie die OkHttp-API, um eine HTTP-Anforderung in Kotlin zu erstellen
  6. Abschluss
Erstellen Sie eine HTTP-Anfrage in Kotlin

HTTP ist ein Kommunikationsprotokoll für das Web und ist für die Bereitstellung von Webinhalten von einem Webserver an den Webbrowser verantwortlich.

Der Webinhalt kann statische Daten oder dynamische Daten sein. Statische Daten bedeuten, dass sich die auf einer Seite angezeigten Informationen nicht ändern, während sich die auf einer Webseite angezeigten dynamischen Daten ständig ändern.

Die von einem Server abgerufenen Daten umfassen strukturierte Daten, Bild- und Videodateien. Die meisten Anwendungen arbeiten in der Regel mit strukturierten Daten, die von einer Datenbank verwaltet werden.

Ein gängiger Ansatz beim Abrufen von Daten aus der Datenbank zum Webclient ist die Verwendung von Restful-APIs. Die Restful-APIs werden von der Anwendung unter Verwendung verschiedener Bibliotheken über das HTTP-Protokoll verwendet und in den Webclient geladen.

In diesem Tutorial lernen wir die verschiedenen Möglichkeiten kennen, mit denen wir eine HTTP-Anforderung erstellen können, die eine Restful-API verwendet. Die Restful-API gibt eine Liste von Ländern aus einer Anwendung zurück, die auf Heroku gehostet wird.

Erstellen Sie ein Kotlin-Projekt und fügen Sie Abhängigkeiten hinzu

Öffnen Sie die IntelliJ-Entwicklungsumgebung und wählen Sie Datei > Neu > Projekt. Geben Sie im sich öffnenden Fenster den Namen des Projekts als kotlin-http-request ein, wählen Sie Kotlin im Abschnitt Sprache und wählen Sie Gradle im Abschnitt System erstellen.

Drücken Sie abschließend die Schaltfläche Erstellen, um das Projekt zu generieren.

Öffnen Sie die Datei build.gradle.kts und stellen Sie sicher, dass Sie alle im folgenden Code gezeigten Abhängigkeiten haben. Diese Abhängigkeiten helfen uns, die Bibliotheken hinzuzufügen, die wir zum Erstellen von HTTP-Anforderungen verwenden können.

dependencies{
    implementation ("com.squareup.retrofit2:retrofit:2.9.0")
    implementation ("com.squareup.retrofit2:converter-gson:2.9.0")
    implementation ("com.github.kittinunf.fuel:fuel:2.3.1")
    implementation ("com.squareup.okhttp3:okhttp:4.10.0")
    testImplementation(kotlin("test"))
}

Verwenden Sie Retrofit, um eine HTTP-Anforderung in Kotlin zu erstellen

Retrofit ist die am häufigsten verwendete Bibliothek bei der Entwicklung von Anwendungen mit Kotlin oder Java.

Erstellen Sie unter dem Ordner kotlin einen Ordner mit dem Namen model. Erstellen Sie eine Datei namens Country.kt und kopieren Sie den folgenden Code und fügen Sie ihn in die Datei ein.

package model

data class Country(var id: Number,
              var countryName: String);

In diesem Code haben wir eine Datenklasse erstellt, die wir verwenden werden, um die vom Server abgerufenen Länder-Objekte zu speichern. Die Klasse hat die Felder id und countryName, die den Feldern der vom Server abgerufenen Objekte zugeordnet werden.

Erstellen Sie unter dem Ordner kotlin einen Ordner mit dem Namen service. Erstellen Sie eine Datei mit dem Namen CountryService.kt und kopieren Sie den folgenden Code und fügen Sie ihn in die Datei ein.

package service

import model.Country
import retrofit2.Call
import retrofit2.http.GET

interface CountryService {
    @GET("/country/all")
    fun getAllCountries(): Call<List<Country>>;
}

In diesem Code haben wir eine GET-Anforderung erstellt, die dem relativen Pfad /country/all zugeordnet ist, um alle Länder List<Country> vom Server abzurufen. Wir verwenden immer die Annotation @GET, wenn wir Daten von einem Server abrufen möchten.

Beachten Sie, dass die Methode getAllCountries() einen Call zurückgibt, was bedeutet, dass die Methode eine Anfrage an den Server stellt und eine Antwort zurückgibt.

Erstellen Sie eine Datei mit dem Namen CountryServiceImpl.kt und kopieren Sie den folgenden Code und fügen Sie ihn in die Datei ein.

package service

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

class CountryServiceImpl {
    fun getCountryServiceFactory(): CountryService{
        val retrofit = Retrofit.Builder()
            .baseUrl("https://countryapp254.herokuapp.com")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

        return retrofit.create(CountryService::class.java);
    }
}

Diese Klasse erledigt die Hauptarbeit beim Abrufen der Daten vom Server, indem sie die relative URL, die wir in der Methode getAllCountries() bereitgestellt haben, mit der dem Builder bereitgestellten baseUrl() zuordnet.

Die addConverterFactory() hilft uns bei der Deserialisierung der Kotlin-Objekte mit Hilfe der Gson-Bibliothek, die ebenfalls von Retrofit bereitgestellt wird.

Erstellen Sie eine Main.kt-Datei im Ordner kotlin und kopieren Sie den folgenden Code und fügen Sie ihn in die Datei ein.

import model.Country
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import service.CountryService
import service.CountryServiceImpl

fun getAllCountriesUsingRetrofit(){
    val countryService: CountryService =
        CountryServiceImpl().getCountryServiceFactory();

    val call: Call<List<Country>> = countryService.getAllCountries();

    call.enqueue(object : Callback<List<Country>> {
        override fun onResponse(call: Call<List<Country>>,
                                response: Response<List<Country>>
        ) {
            response.body()?.forEach(::println)
        }

        override fun onFailure(call: Call<List<Country>>, t: Throwable) {
            t.printStackTrace();
        }

    })
}

fun main(){
    getAllCountriesUsingRetrofit();
}

Der obige Code überprüft, ob unser Retrofit-Code funktioniert. Rufen Sie getCountryServiceFactory() auf, das einen CountryService zurückgibt.

Die Instanz CountryService hilft uns, die Methode getAllCountries() aufzurufen. Die Methode liefert einen Call zurück, der eine Antwort auf unsere Daten enthält.

Um die vom Server abgerufenen Länder zu erhalten, rufen Sie die Methode enqueue() auf und implementieren Sie die Methoden onResponse() und onFailure() des CallBack.

Die Methode enqueue() wird asynchron ausgeführt, und da wir eine Konsolenanwendung erstellen, müssen wir nur die Antwort body() an die Konsole protokollieren. Führen Sie diesen Code aus und stellen Sie sicher, dass die Ausgabe wie unten gezeigt ist.

[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]

Verwenden Sie eine API der Java-Standardbibliothek, um eine HTTP-Anforderung in Kotlin zu erstellen

Kommentieren Sie das vorherige Beispiel in der Datei Main.kt und kopieren Sie den folgenden Code und fügen Sie ihn in die Datei dahinter ein.

import java.net.HttpURLConnection
import java.net.URL

fun getCountriesUsingHttpURLConnection(){
    var url = URL("https://countryapp254.herokuapp.com/country/all");

    with(url.openConnection() as HttpURLConnection){
        inputStream.bufferedReader().use {
            it.lines().forEach(::println)
        }
    }
}

fun main(){
    getCountriesUsingHttpURLConnection();
}

Die URLConnection ist eine API der Java-Standardbibliothek aus dem Paket java.net und kann in Kotlin verwendet werden, um HTTP-Anfragen zu stellen.

Die HttpURLConnection ist eine Instanz von URLConnection und wir verwenden sie, um eine HTTP-Verbindung zu unserem Server herzustellen. Die with()-Funktion stellt über die hergestellte Verbindung eine einzelne Anfrage an den Server, führt den Code innerhalb der Funktion aus und gibt unser Ergebnis zurück.

Der inputStream innerhalb der Funktion liest die Daten aus der hergestellten Verbindung mit einem bufferedReader() und die Erweiterungsfunktion use() hilft uns, die vom Server gelesenen Daten auf der Konsole zu protokollieren. Führen Sie diesen Code aus und stellen Sie sicher, dass die Ausgabe wie unten gezeigt ist.

[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]

Verwenden Sie die Fuel-API, um eine HTTP-Anforderung in Kotlin zu erstellen

Kommentieren Sie das vorherige Beispiel in der Datei Main.kt und kopieren Sie den folgenden Code und fügen Sie ihn in die Datei dahinter ein.

import com.github.kittinunf.fuel.httpGet
import com.github.kittinunf.result.Result

fun getCountriesUsingFuel(){
    val request = "https://countryapp254.herokuapp.com/country/all"
        .httpGet()
        .responseString{ request, response, result ->
            when(result){
                is Result.Failure -> {
                    println(result.getException());
                }

                is Result.Success -> {
                    println(result.get())
                }
            }
        }

    request.join();
}

fun main(){
    getCountriesUsingFuel();
}

Die Fuel-API ist ein weiterer Ansatz, den wir verwenden können, um HTTP-Anforderungen in unseren Anwendungen zu erstellen. In diesem Beispiel haben wir httpGet() aufgerufen, eine Erweiterungsfunktion der String-Klasse, um anzuzeigen, dass wir eine GET-Anfrage stellen.

Die Zeichenfolge stellt die RESTful-API bereit, die zum Abrufen von Daten vom Server verwendet wird.

Die Methode httpGet() gibt eine Request zurück, die es uns ermöglicht, die Methode responseString() aufzurufen, um die Anfrage asynchron in einer Charset.UTF-8 auszuführen, indem ein Handler als Argument übergeben wird.

Der Handler ist eine Lambda-Funktion, die drei Parameter vom Typ Request, Response und Result akzeptiert und eine Unit zurückgibt, was bedeutet, dass sie keinen Wert zurückgibt. Da uns das Ergebnis interessiert, rufen wir Fehler und Erfolg auf, die beide ein Ergebnis liefern, wenn die Anwendung fehlgeschlagen bzw. erfolgreich war.

Die Methode when() ist die gleiche wie switch in Java und hilft uns, unterschiedliche Entscheidungen zu treffen, wenn die Anfrage erfolgreich war oder fehlgeschlagen ist. Führen Sie diesen Code aus und stellen Sie sicher, dass die Ausgabe wie unten gezeigt ist.

[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]

Verwenden Sie die OkHttp-API, um eine HTTP-Anforderung in Kotlin zu erstellen

Kommentieren Sie das vorherige Beispiel in der Datei Main.kt und kopieren Sie den folgenden Code und fügen Sie ihn in die Datei dahinter ein.

import okhttp3.OkHttpClient
import okhttp3.Request

private val httpClient = OkHttpClient()

fun getCountriesUsingOkHttp() {
    val countriesRequest = Request.Builder()
        .url("https://countryapp254.herokuapp.com/country/all")
        .build();

    httpClient.newCall(countriesRequest).execute().use { countryResponse ->
        if (!countryResponse.isSuccessful) throw RuntimeException("status code $countryResponse");

        println(countryResponse.body!!.string())
    }
}

fun main(){
    getCountriesUsingOkHttp();
}

Der OkHttpClient() erstellt eine gemeinsame API-Instanz, die wir verwenden können, um HTTP-Anfragen an den Server zu stellen.

Die gemeinsam genutzte Instanz wird erstellt, weil jeder Client über seine Thread-Pools und Verbindungspools verfügt und deren Wiederverwendung wichtig ist, um Arbeitsspeicher zu sparen und die Latenz zu reduzieren.

Der Builder() erstellt eine Anfrage unter Verwendung der bereitgestellten URL, und um eine Anfrage an den Server vorzubereiten, rufen wir die newCall()-Methode von der OkHttpClient()-Instanz auf und übergeben die Anfrage als Argument dieser Methode.

Die Methode newCall() gibt einen Call zurück und wir rufen ihre Methode execute() auf, um die Antwort auf die Anfrage von Response.body() zu erhalten. Die Erweiterungsfunktion use() hilft uns, auf die Daten der Antwort zuzugreifen und sie in der Konsole zu protokollieren.

Beachten Sie, dass die Funktion use() das Ergebnis unabhängig davon schließt, ob eine Ausnahme ausgelöst wurde oder nicht. Führen Sie diesen Code aus und stellen Sie sicher, dass die Ausgabe wie unten gezeigt ist.

[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]

Abschluss

In diesem Tutorial haben wir verschiedene Möglichkeiten kennengelernt, die wir nutzen können, um HTTP-Anforderungen in Kotlin zu erstellen. Die von uns behandelten Ansätze umfassen die Verwendung von Retrofit, die Verwendung einer API der Java-Standardbibliothek, die Verwendung der Fuel-API und schließlich die Verwendung der OkHttp-API.

Beachten Sie, dass dies nicht die einzigen Ansätze sind, die wir verwenden können; Es gibt andere Ansätze, die wir verwenden können, wie z. B. die Volley-API. Fühlen Sie sich frei, jede Methode zu verwenden, die für Ihren Anwendungsfall geeignet ist.

David Mbochi Njonge avatar David Mbochi Njonge avatar

David is a back end developer with a major in computer science. He loves to solve problems using technology, learning new things, and making new friends. David is currently a technical writer who enjoys making hard concepts easier for other developers to understand and his work has been published on multiple sites.

LinkedIn GitHub