Ich bin völlig neu in Kotlin. Ich möchte eine Anmeldeüberprüfung mit der POST-Methode durchführen und einige Informationen mit der GET-Methode abrufen. Ich habe bereits URL, Server-Benutzername und Passwort meines vorherigen Projekts. Ich habe kein richtiges Beispielprojekt gefunden, das dieses Ding verwendet. Jeder schlägt mir bitte ein Arbeitsbeispiel vor, in dem ich die GET- und POST-Methode in HTTP-Anfragen verwenden kann
73
Antworten:
Für Android ist Volley ein guter Ort, um loszulegen. Für alle Plattformen möchten Sie möglicherweise auch ktor client oder http4k ausprobieren, die beide gute Bibliotheken sind.
Sie können jedoch auch Standard-Java-Bibliotheken verwenden,
java.net.HttpURLConnection
die Teil des Java SDK sind:fun sendGet() { val url = URL("http://www.google.com/") with(url.openConnection() as HttpURLConnection) { requestMethod = "GET" // optional default is GET println("\nSent 'GET' request to URL : $url; Response Code : $responseCode") inputStream.bufferedReader().use { it.lines().forEach { line -> println(line) } } } }
Oder einfacher:
URL("https://google.com").readText()
quelle
Senden Sie eine HTTP-POST / GET-Anforderung mit Parametern mithilfe von
HttpURLConnection
:POST mit Parametern:
fun sendPostRequest(userName:String, password:String) { var reqParam = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(userName, "UTF-8") reqParam += "&" + URLEncoder.encode("password", "UTF-8") + "=" + URLEncoder.encode(password, "UTF-8") val mURL = URL("<Your API Link>") with(mURL.openConnection() as HttpURLConnection) { // optional default is GET requestMethod = "POST" val wr = OutputStreamWriter(getOutputStream()); wr.write(reqParam); wr.flush(); println("URL : $url") println("Response Code : $responseCode") BufferedReader(InputStreamReader(inputStream)).use { val response = StringBuffer() var inputLine = it.readLine() while (inputLine != null) { response.append(inputLine) inputLine = it.readLine() } println("Response : $response") } } }
GET mit Parametern:
fun sendGetRequest(userName:String, password:String) { var reqParam = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(userName, "UTF-8") reqParam += "&" + URLEncoder.encode("password", "UTF-8") + "=" + URLEncoder.encode(password, "UTF-8") val mURL = URL("<Yout API Link>?"+reqParam) with(mURL.openConnection() as HttpURLConnection) { // optional default is GET requestMethod = "GET" println("URL : $url") println("Response Code : $responseCode") BufferedReader(InputStreamReader(inputStream)).use { val response = StringBuffer() var inputLine = it.readLine() while (inputLine != null) { response.append(inputLine) inputLine = it.readLine() } it.close() println("Response : $response") } } }
quelle
url
undinputStream
vars definiert? Dieser Code ist unvollständig.it.close
.Vielleicht das einfachste GET
Für alle, die mit NetworkOnMainThreadException für die anderen Lösungen nicht weiterkommen: Verwenden Sie AsyncTask oder, noch kürzer, (noch experimentell) Coroutines:
launch { val jsonStr = URL("url").readText() }
Wenn Sie mit einfachem http testen müssen, vergessen Sie nicht, Ihrem Manifest Folgendes hinzuzufügen:
android:usesCleartextTraffic="true"
Für die experimentellen Coroutinen müssen Sie build.gradle ab dem 10.10.2008 hinzufügen:
kotlin { experimental { coroutines 'enable' } } dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.24.0" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.24.0" ...
quelle
readText
- ist es in Ordnung,readText
Coroutinen anstelle von Threads zu verwenden?Wenn Sie verwenden
Kotlin
, können Sie Ihren Code so kurz wie möglich halten. Dierun
Methode verwandelt den Empfänger inthis
und gibt den Wert des Blocks zurück.this as HttpURLConnection
erstellt eine intelligente Besetzung.bufferedReader().readText()
vermeidet eine Menge Boilerplate-Code.return URL(url).run { openConnection().run { this as HttpURLConnection inputStream.bufferedReader().readText() } }
Sie können dies auch in eine Erweiterungsfunktion einbinden.
fun URL.getText(): String { return openConnection().run { this as HttpURLConnection inputStream.bufferedReader().readText() } }
Und nenne es so
return URL(url).getText()
Wenn Sie sehr faul sind, können Sie
String
stattdessen die Klasse erweitern.fun String.getUrlText(): String { return URL(this).run { openConnection().run { this as HttpURLConnection inputStream.bufferedReader().readText() } } }
Und nenne es so
return "http://somewhere.com".getUrlText()
quelle
InputStream
, wieinputStream.bufferedReader().use {readText()}
Schauen Sie sich die Kraftstoffbibliothek an , eine Beispiel- GET-Anfrage
"https://httpbin.org/get" .httpGet() .responseString { request, response, result -> when (result) { is Result.Failure -> { val ex = result.getException() } is Result.Success -> { val data = result.get() } } } // You can also use Fuel.get("https://httpbin.org/get").responseString { ... } // You can also use FuelManager.instance.get("...").responseString { ... }
Eine Beispiel- POST-Anfrage
Fuel.post("https://httpbin.org/post") .jsonBody("{ \"foo\" : \"bar\" }") .also { println(it) } .response { result -> }
Ihre Dokumentation findet sich hier
quelle
Ich denke, die Verwendung von okhttp ist die einfachste Lösung. Hier sehen Sie ein Beispiel für die POST-Methode, das Senden eines JSON und mit auth.
val url = "https://example.com/endpoint" val client = OkHttpClient() val JSON = MediaType.get("application/json; charset=utf-8") val body = RequestBody.create(JSON, "{\"data\":\"$data\"}") val request = Request.Builder() .addHeader("Authorization", "Bearer $token") .url(url) .post(body) .build() val response = client . newCall (request).execute() println(response.request()) println(response.body()!!.string())
Denken Sie daran, diese Abhängigkeit zu Ihrem Projekt https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp hinzuzufügen
UPDATE: 7. Juli 2019 Ich werde zwei Beispiele mit dem neuesten Kotlin (1.3.41), OkHttp (4.0.0) und Jackson (2.9.9) geben.
Methode abrufen
fun get() { val client = OkHttpClient() val url = URL("https://reqres.in/api/users?page=2") val request = Request.Builder() .url(url) .get() .build() val response = client.newCall(request).execute() val responseBody = response.body!!.string() //Response println("Response Body: " + responseBody) //we could use jackson if we got a JSON val mapperAll = ObjectMapper() val objData = mapperAll.readTree(responseBody) objData.get("data").forEachIndexed { index, jsonNode -> println("$index $jsonNode") } }
POST-Methode
fun post() { val client = OkHttpClient() val url = URL("https://reqres.in/api/users") //just a string var jsonString = "{\"name\": \"Rolando\", \"job\": \"Fakeador\"}" //or using jackson val mapperAll = ObjectMapper() val jacksonObj = mapperAll.createObjectNode() jacksonObj.put("name", "Rolando") jacksonObj.put("job", "Fakeador") val jacksonString = jacksonObj.toString() val mediaType = "application/json; charset=utf-8".toMediaType() val body = jacksonString.toRequestBody(mediaType) val request = Request.Builder() .url(url) .post(body) .build() val response = client.newCall(request).execute() val responseBody = response.body!!.string() //Response println("Response Body: " + responseBody) //we could use jackson if we got a JSON val objData = mapperAll.readTree(responseBody) println("My name is " + objData.get("name").textValue() + ", and I'm a " + objData.get("job").textValue() + ".") }
quelle
Sie können die Kohttp- Bibliothek verwenden. Es ist ein Kotlin DSL HTTP-Client. Es unterstützt die Funktionen von square.okhttp und bietet ihnen ein klares DSL. Asynchrone KoHttp-Aufrufe werden von Coroutinen unterstützt.
httpGet
Erweiterungsfunktionval response: Response = "https://google.com/search?q=iphone".httpGet()
Sie können auch einen asynchronen Aufruf mit Coroutinen verwenden
val response: Deferred<Response> = "https://google.com/search?q=iphone".asyncHttpGet()
oder DSL-Funktion für komplexere Anforderungen
val response: Response = httpGet { host = "google.com" path = "/search" param { "q" to "iphone" "safe" to "off" } }
Weitere Details finden Sie in den Dokumenten
Um es mit Gradle zu bekommen, benutze
implementation 'io.github.rybalkinsd:kohttp:0.12.0'
quelle
fun httpGet(client: Call.Factory = defaultHttpClient, init: HttpGetContext.() -> Unit): Response
dass sie Call Factory mit einer Konfiguration verwenden kann, die für Ihre Projektanforderungen und Leistungsprobleme spezifisch ist.Verwenden Sie nur die Standardbibliothek mit minimalem Code!
thread { val jsonStr = try { URL(url).readText() } catch (ex: Exception) { return@thread } runOnUiThread { displayOrWhatever(jsonStr) } }
Dadurch wird eine GET-Anforderung für einen neuen Thread gestartet , sodass der UI-Thread auf Benutzereingaben reagieren kann. Wir können jedoch nur UI-Elemente aus dem Haupt- / UI-Thread ändern, sodass wir tatsächlich einen
runOnUiThread
Block benötigen , um das Ergebnis unserem Benutzer anzuzeigen. Dadurch wird unser Anzeigecode in die Warteschlange gestellt, damit er bald auf dem UI-Thread ausgeführt werden kann.Der Versuch / Fang ist da, damit Ihre App nicht abstürzt, wenn Sie eine Anfrage mit ausgeschaltetem Internet Ihres Telefons stellen. Fügen Sie nach Belieben Ihre eigene Fehlerbehandlung hinzu (z. B. Anzeigen eines Toasts).
.readText()
ist nicht Teil derjava.net.URL
Klasse, sondern eine Kotlin- Erweiterungsmethode . Kotlin "klebt" diese Methode aufURL
. Dies reicht für einfache GET-Anforderungen aus, aber für mehr Kontrolle und POST-Anforderungen benötigen Sie so etwas wie dieFuel
Bibliothek.quelle
import java.io.IOException import java.net.URL fun main(vararg args: String) { val response = try { URL("http://seznam.cz") .openStream() .bufferedReader() .use { it.readText() } } catch (e: IOException) { "Error with ${e.message}." } println(response) }
quelle
Ohne zusätzliche Abhängigkeiten hinzuzufügen, funktioniert dies. Dafür brauchst du keinen Volley. Dies funktioniert mit der aktuellen Version von Kotlin ab Dezember 2018: Kotlin 1.3.10
Wenn Sie Android Studio verwenden, müssen Sie diese Deklaration in Ihre AndroidManifest.xml einfügen:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Sie sollten Importe hier manuell deklarieren. Das Auto-Import-Tool hat mir viele Konflikte verursacht:
import android.os.AsyncTask import java.io.BufferedReader import java.io.InputStreamReader import java.io.OutputStream import java.io.OutputStreamWriter import java.net.URL import java.net.URLEncoder import javax.net.ssl.HttpsURLConnection
Sie können keine Netzwerkanforderungen für einen Hintergrundthread ausführen. Sie müssen Unterklasse
AsyncTask
.So rufen Sie die Methode auf:
Erklärung:
private class NetworkTask : AsyncTask<String, Int, Long>() { override fun doInBackground(vararg parts: String): Long? { val requestURL = parts.first() val queryString = parts.last() // Set up request val connection: HttpsURLConnection = URL(requestURL).openConnection() as HttpsURLConnection // Default is GET so you must override this for post connection.requestMethod = "POST" // To send a post body, output must be true connection.doOutput = true // Create the stream val outputStream: OutputStream = connection.outputStream // Create a writer container to pass the output over the stream val outputWriter = OutputStreamWriter(outputStream) // Add the string to the writer container outputWriter.write(queryString) // Send the data outputWriter.flush() // Create an input stream to read the response val inputStream = BufferedReader(InputStreamReader(connection.inputStream)).use { // Container for input stream data val response = StringBuffer() var inputLine = it.readLine() // Add each line to the response container while (inputLine != null) { response.append(inputLine) inputLine = it.readLine() } it.close() // TODO: Add main thread callback to parse response println(">>>> Response: $response") } connection.disconnect() return 0 } protected fun onProgressUpdate(vararg progress: Int) { } override fun onPostExecute(result: Long?) { } }
quelle
GET und POST mit OkHttp
private const val CONNECT_TIMEOUT = 15L private const val READ_TIMEOUT = 15L private const val WRITE_TIMEOUT = 15L private fun performPostOperation(urlString: String, jsonString: String, token: String): String? { return try { val client = OkHttpClient.Builder() .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS) .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS) .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS) .build() val body = jsonString.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull()) val request = Request.Builder() .url(URL(urlString)) .header("Authorization", token) .post(body) .build() val response = client.newCall(request).execute() response.body?.string() } catch (e: IOException) { e.printStackTrace() null } } private fun performGetOperation(urlString: String, token: String): String? { return try { val client = OkHttpClient.Builder() .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS) .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS) .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS) .build() val request = Request.Builder() .url(URL(urlString)) .header("Authorization", token) .get() .build() val response = client.newCall(request).execute() response.body?.string() } catch (e: IOException) { e.printStackTrace() null } }
Objektserialisierung und Deserialisierung
@Throws(JsonProcessingException::class) fun objectToJson(obj: Any): String { return ObjectMapper().writeValueAsString(obj) } @Throws(IOException::class) fun jsonToAgentObject(json: String?): MyObject? { return if (json == null) { null } else { ObjectMapper().readValue<MyObject>(json, MyObject::class.java) } }
Abhängigkeiten
Fügen Sie die folgenden Zeilen in Ihre Gradle ( App ) -Datei ein. Jackson ist optional. Sie können es für die Serialisierung und Deserialisierung von Objekten verwenden.
implementation 'com.squareup.okhttp3:okhttp:4.3.1' implementation 'com.fasterxml.jackson.core:jackson-core:2.9.8' implementation 'com.fasterxml.jackson.core:jackson-annotations:2.9.8' implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
quelle