動機
- ググっても簡単に使えるHTTPクライアントが見つからなかったので、Okhttp3とcoroutinesを使って作ってみました
HTTPクライアント
import kotlinx.coroutines.*
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import org.json.JSONObject
import java.io.IOException
class HttpClient {
companion object {
val instance = OkHttpClient()
fun get(url: String): JSONObject {
val request = Request.Builder()
.url(url)
.build()
val response = instance.newCall(request).execute()
return JSONObject(response.body?.string().orEmpty())
}
fun getAsync(url: String, onFailed: (Exception) -> Unit = {}, onSuccess: (JSONObject) -> Unit = {}) {
GlobalScope.launch(Dispatchers.Main) {
try {
coroutineScope {
async(Dispatchers.Default) { get(url) }.await().let {
onSuccess(it)
}
}
} catch (e: Exception) {
onFailed(e)
}
}
}
fun post(url: String, params: Map<String, String>? = null): JSONObject {
val formBuilder = FormBody.Builder()
params?.forEach { (name: String, value: String) -> formBuilder.add(name, value) }
val requestBody: RequestBody = formBuilder.build()
val request = Request.Builder()
.url(url)
.post(requestBody)
.build()
val response = instance.newCall(request).execute()
if (!response.isSuccessful) throw IOException("Unexpected code $response");
return JSONObject(response.body?.string().orEmpty())
}
fun postAsync(url: String, params: Map<String, String>? = null, onFailed: (Exception) -> Unit = {}, onSuccess: (JSONObject) -> Unit = {}) {
GlobalScope.launch(Dispatchers.Main) {
try {
coroutineScope {
async(Dispatchers.Default) { post(url, params) }.await().let {
onSuccess(it)
}
}
} catch (e: Exception) {
onFailed(e)
}
}
}
}
}
使い方
同期的にGET
val response = HttpClient.get("https://hoge/api/fuga")
Log.i(TAG, "同期的にGET:${response}")
非同期でGET
HttpClient.getAsync("https://hoge/api/fuga"){
Log.i(TAG, "非同期でGET:${it}")
}
同期的にPOST
val params = mapOf(
"name" to "ryota",
"job" to "neet"
)
val response = HttpClient.post("https://hoge/api/fuga", params)
Log.i(TAG, "同期的にPOST:${response}")
非同期でPOST
val params = mapOf(
"name" to "ryota",
"job" to "neet"
)
HttpClient.postAsync("https://hoge/api/fuga", params) {
Log.i(TAG, "非同期でPOST:${it}")
}
非同期でPOST + エラーハンドリング
val handleError: (Exception) -> Unit = {
e -> Log.e(TAG, "エラー:${e}")
}
HttpClient.postAsync("https://hoge/api/fuga", params, onFailed = handleError) {
Log.i(TAG, "非同期でPOST + エラーハンドリング:${it}")
}
使いやすいようにカスタマイズして使って下さい。