お疲れさまです。@naokiurです。
よろしくお願い致します。
今回は、KotlinでHTTPアクセスを実施したいと思います。
環境
- MacBook Pro (Retina 13-inch、Early 2015)
- macOS High Sierra 10.13.6
- Java 1.8.0_191
- IntelliJ IDEA CE 2018.3.4
実施したこと
- ローカルサーバーの作成
- 確認用
- GET
- レスポンス: text
- レスポンス: json
- クライアントの作成
結果
- クライアントからサーバーへHTTPリクエストを送ってレスポンスを取得することができた。
ローカルサーバーの作成
せっかくなので、KtorでAPIサーバーを作成します。
クライアントからこれにアクセスし、確認するためです。
package jp.ne.naokiur.sample.fuel
import com.google.gson.GsonBuilder
import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.application.install
import io.ktor.features.CallLogging
import io.ktor.features.Compression
import io.ktor.features.ContentNegotiation
import io.ktor.features.DefaultHeaders
import io.ktor.gson.gson
import io.ktor.response.respond
import io.ktor.response.respondText
import io.ktor.routing.get
import io.ktor.routing.routing
import java.text.DateFormat
fun Application.fuelSampleApi() {
install(DefaultHeaders)
install(Compression)
install(CallLogging)
install(ContentNegotiation) {
gson {
setDateFormat(DateFormat.LONG)
setPrettyPrinting()
}
}
routing {
get("/") {
call.respondText("fuel sample api!")
}
get("/text") {
call.respondText("access Text!")
}
get("/json") {
val gson = GsonBuilder().setPrettyPrinting().create()
val res = mapOf("message" to "access json!", "a" to "1", "b" to "2")
call.respond(gson.toJson(res))
}
}
}
GETリクエストを送信すると、
それぞれtextとJSONを返却するローカルサーバーを作成しました。
これを確認用にしたいと思います。
クライアントの作成
Fuelの公式を拝見しつつ、
作成していきます。
レスポンス: text
Fuelのインストール
build.gradleに追加します。
buildscript {
ext.fuel_version = '2.2.0'
// 中略
}
dependencies {
implementation "com.github.kittinunf.fuel:fuel:$fuel_version"
// 中略
}
クラス・メソッドの作成
HTTPアクセスするクラスを作成します。
package jp.ne.naokiur.sample.fuel
import com.github.kittinunf.fuel.httpGet
import com.github.kittinunf.result.Result
class HttpAccessor {
fun getText(url: String): String {
val (_, _, result) = url.httpGet().responseString()
return when (result) {
is Result.Failure -> {
val ex = result.getException()
ex.toString()
}
is Result.Success -> {
result.get()
}
}
}
}
responseString()
は同期的に処理してくれるそうです。
Tripleで返却されるため、分解宣言をし、
今回必要としている、Result
だけ、受け取ります。
これを実行するメソッドを作成します。
package jp.ne.naokiur.sample.fuel
fun main() {
val accessor = HttpAccessor()
// Text
val resultText = accessor.getText("http://localhost:8080/text")
println(resultText)
}
レスポンス: json
Fuel-jsonのインストール
Fuelには、いくつものデシリアライザが用意されており、
その中でJSON形式もあります。
便利ですね。
build.gradleに追加します。
buildscript {
ext.fuel_version = '2.2.0'
// 中略
}
dependencies {
implementation "com.github.kittinunf.fuel:fuel:$fuel_version"
implementation "com.github.kittinunf.fuel:fuel-json:$fuel_version" // 追加
// 中略
}
メソッドの作成
レスポンスのJSONを扱いやすいように変換した上で、
返却するメソッドにしたいと思います。
package jp.ne.naokiur.sample.fuel
import com.github.kittinunf.fuel.httpGet
import com.github.kittinunf.fuel.json.responseJson
import com.github.kittinunf.result.Result
import org.json.JSONObject
class HttpAccessor {
// 中略
fun getJson(url: String): JSONObject {
val (_, _, result) = url.httpGet().responseJson()
return when (result) {
is Result.Failure -> {
val ex = result.getException()
JSONObject(mapOf("message" to ex.toString()))
}
is Result.Success -> {
result.get().obj()
}
}
}
}
メソッドに、これを実行する処理を追加します。
package jp.ne.naokiur.sample.fuel
fun main() {
val accessor = HttpAccessor()
// Text
val resultText = accessor.getText("http://localhost:8080/text")
println(resultText)
// JSON
val resultJson = accessor.getJson("http://localhost:8080/json")
println(resultJson.get("message"))
println(resultJson.get("a"))
println(resultJson.get("b"))
}
結果
Intellijのランナーで FuelSampleMain.kt
を実行すると、
以下のように出力され、
アクセスできたことが確認できました。
今後
- エラーハンドリングが雑なので、付け加えていきたいと思います。
- GETメソッドしか試していないため、他のメソッドも試したいと思います。
- 拡張性・再利用性のあるクラスにリファクタリングしていきたいと思います。