[JAVA] Wirf eine PATCH-Anfrage mit HttpURLConnection

Wenn ich beim Erstellen einer Android-Anwendung eine API-Kommunikation durchführen wollte, musste ich diese aus irgendeinem Grund ohne Verwendung der OSS-Bibliothek implementieren. Daher habe ich mit HttpURLConnection meinen eigenen Kommunikationsteil erstellt.

Es tritt jedoch ein Fehler auf, wenn ich eine PATCH-Anfrage senden möchte. Es scheint, dass HttpURLConnection keine PATCH-Anfragen stellen kann. Lüge ... richtig ...

Es gibt auch eine Möglichkeit, mit dem Header "X-HTTP-Method-Override" zu fälschen, dies scheint jedoch aufgrund serverseitiger Abhängigkeiten ungewiss zu sein. https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch

Wie macht man die OSS-Bibliothek? Lesen Sie daher Öffentlicher Code der HTTP-Clientbibliothek mit dem Namen Jersey. Und implementiert. Es ist eine kleine alte Bibliothek, aber ich konnte ihren Betrieb bestätigen.

Implementierungsbeispiel

Implementieren Sie die Klasse "HttpClient" wie folgt. Dieses Mal wird die Inhaberauthentifizierung angenommen.

HttpClient.kt



internal class HttpClient {
    companion object {

        fun patch(url: String, accessToken: String? = null, body: String? = null): Pair<Int, String?> {
            var responseJsonString: String? = null
            val urlTmp = URL(url)
            val con = urlTmp.openConnection() as HttpURLConnection
            try {
                setRequestMethodViaJreBugWorkaround( con, "PATCH")
                con.instanceFollowRedirects = false
                con.doOutput = true
                con.connectTimeout = 60000
                con.readTimeout = 60000
                con.setRequestProperty("Content-Type", "application/json")
                con.setRequestProperty("Accept", "application/json")
                if(accessToken != null) con.setRequestProperty("Authorization", "Bearer $accessToken")
                if(body != null) {
                    val os: OutputStream = con.outputStream
                    val ps = PrintStream(os)
                    ps.print(body)
                    ps.close()
                }
                val reader: BufferedReader
                reader = if (con.responseCode == HttpURLConnection.HTTP_OK) {
                    BufferedReader(InputStreamReader(con.inputStream, "UTF-8"))
                } else {
                    BufferedReader(InputStreamReader(con.errorStream, "UTF-8"))
                }
                responseJsonString = reader.readLine()
                con.disconnect()
            } catch (e: Exception) {
                e.printStackTrace()
                Log.e("ApiClientException", e.toString())
            }
            return con.responseCode to responseJsonString
        }

        private fun setRequestMethodViaJreBugWorkaround(httpURLConnection: HttpURLConnection, method: String) {
            try {
                httpURLConnection.requestMethod = method // Check whether we are running on a buggy JRE
            } catch (pe: ProtocolException) {
                try {
                    AccessController.doPrivileged(PrivilegedExceptionAction<Any?> {
                        try {
                            httpURLConnection.requestMethod = method
                            // Check whether we are running on a buggy
                            // JRE
                        } catch (pe: ProtocolException) {
                            var connectionClass: Class<*>? = httpURLConnection.javaClass
                            val delegateField: Field?
                            try {
                                delegateField = connectionClass!!.getDeclaredField("delegate")
                                delegateField.isAccessible = true
                                val delegateConnection = delegateField[httpURLConnection] as HttpURLConnection
                                setRequestMethodViaJreBugWorkaround(delegateConnection, method)
                            } catch (e: NoSuchFieldException) {
                                // Ignore for now, keep going
                            } catch (e: IllegalArgumentException) {
                                throw RuntimeException(e)
                            } catch (e: IllegalAccessException) {
                                throw RuntimeException(e)
                            }
                            try {
                                var methodField: Field
                                while (connectionClass != null) {
                                    try {
                                        methodField = connectionClass.getDeclaredField("method")
                                    } catch (e: NoSuchFieldException) {
                                        connectionClass = connectionClass.superclass
                                        continue
                                    }
                                    methodField.isAccessible = true
                                    methodField[httpURLConnection] = method
                                    break
                                }
                            } catch (e: java.lang.Exception) {
                                throw RuntimeException(e)
                            }
                        }
                        null
                    })
                } catch (e: PrivilegedActionException) {
                    val cause: Throwable? = e.cause
                    if (cause is RuntimeException) {
                        throw cause
                    } else {
                        throw RuntimeException(cause)
                    }
                }
            }
        }
    }
}

Anwendungsbeispiel

Importieren Sie den obigen HttpClient und verwenden Sie ihn wie folgt.

fun patchRequestSample() {
    val (statusCode, responseJsonString) = HttpClient.patch("https://hoge/users/10", accessToken ="xxxx", body = sampleJson.toString())
}

Der Statuscode wird in "statusCode" und die Antwort in "responseJsonString" zurückgegeben.

Selbst wenn ich es nachgeschlagen habe, habe ich nur herausgefunden, wie ich den Header überschreiben kann, also werde ich es als Erinnerung belassen.

Recommended Posts

Wirf eine PATCH-Anfrage mit HttpURLConnection
So fordern Sie mit jMeter eine CSV-Datei als JSON an
[Java] Wirf eine Anfrage und zeige den Bildschirm an (GET / POST)
Erstellen Sie einen Spielplatz mit Xcode 12
Eine Geschichte, die bei NotSerializableException steckt
Dinge, die Sie beim Abfangen einer Anfrage mit Android WebView vergessen sollten # shouldInterceptRequest