Lorsque je voulais effectuer une communication API lors de la création d'une application Android, je devais l'implémenter sans utiliser la bibliothèque OSS pour une raison quelconque.
Par conséquent, j'ai créé ma propre partie de communication en utilisant HttpURLConnection
.
Cependant, une erreur se produit lorsque je souhaite envoyer une requête PATCH.
Il semble que HttpURLConnection
ne puisse pas faire de requêtes PATCH.
Mentir ... à droite ...
Il existe également un moyen d'usurper en utilisant l'en-tête X-HTTP-Method-Override
, mais cela semble incertain en raison des dépendances côté serveur.
https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch
Comment faites-vous la bibliothèque OSS? Reportez-vous donc au Code public de la bibliothèque client HTTP appelée Jersey. Et l'a mis en œuvre. C'est une petite bibliothèque ancienne, mais j'ai pu confirmer son fonctionnement.
Implémentez la classe HttpClient
comme suit.
Cette fois, l'authentification du support est supposée.
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)
}
}
}
}
}
}
Importez le HttpClient
ci-dessus et utilisez-le comme suit.
fun patchRequestSample() {
val (statusCode, responseJsonString) = HttpClient.patch("https://hoge/users/10", accessToken ="xxxx", body = sampleJson.toString())
}
Le code d'état est retourné dans statusCode
et la réponse est retournée dans responseJsonString
.
Même si je l'ai recherché, je n'ai trouvé que comment remplacer l'en-tête, je vais donc le laisser comme rappel.
Recommended Posts