MST
星途 面试题库

面试题:Kotlin Ktor客户端中如何处理异步请求及响应

在Kotlin的Ktor客户端开发中,阐述如何使用异步方式发送HTTP请求,并正确处理返回的响应。请举例说明使用到的关键函数和处理流程。
50.0万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试
  1. 引入依赖: 在build.gradle.kts中添加Ktor客户端依赖,例如:

    implementation("io.ktor:ktor-client-core:${ktor_version}")
    implementation("io.ktor:ktor-client-okhttp:${ktor_version}")
    
  2. 创建HttpClient实例

    import io.ktor.client.*
    import io.ktor.client.engine.okhttp.*
    import io.ktor.client.request.*
    
    val client = HttpClient(OkHttp) {
        // 可以在这里配置一些通用的参数,如超时等
    }
    
  3. 异步发送HTTP请求并处理响应: 以GET请求为例:

    import kotlinx.coroutines.runBlocking
    
    fun main() = runBlocking {
        val response = client.get<String>("https://example.com/api/data")
        println(response)
    }
    

    在上述代码中:

    • client.get<String>("https://example.com/api/data")是关键函数。get函数用于发送GET请求,<String>表示期望返回的响应体类型为字符串。这里使用了Kotlin的泛型来指定响应体类型。
    • runBlocking用于在主线程中启动一个协程。在实际的Android或服务器应用中,可能会在合适的协程作用域内进行请求,而不是使用runBlocking

    对于POST请求,可以这样写:

    import kotlinx.coroutines.runBlocking
    import io.ktor.client.request.*
    
    fun main() = runBlocking {
        val response = client.post<String>("https://example.com/api/submit") {
            contentType(ContentType.Application.Json)
            setBody("""{"key":"value"}""")
        }
        println(response)
    }
    
    • client.post<String>("https://example.com/api/submit")用于发送POST请求。
    • post的闭包内,contentType(ContentType.Application.Json)设置请求体的类型为JSON格式,setBody("""{"key":"value"}""")设置请求体的内容。
  4. 处理不同类型的响应: 如果期望的响应体是自定义的数据类,可以这样:

    data class MyDataClass(val id: Int, val name: String)
    
    fun main() = runBlocking {
        val response = client.get<MyDataClass>("https://example.com/api/data")
        println(response.id)
        println(response.name)
    }
    
    • 这里假设服务器返回的JSON数据可以映射到MyDataClass。Ktor客户端会自动根据响应的JSON数据反序列化到MyDataClass实例。
  5. 错误处理: 可以使用try - catch块来处理请求过程中的异常,例如:

    import io.ktor.client.call.*
    import io.ktor.client.plugins.*
    import kotlinx.coroutines.runBlocking
    
    fun main() = runBlocking {
        try {
            val response = client.get<String>("https://example.com/api/data")
            println(response)
        } catch (e: ClientRequestException) {
            println("请求异常: ${e.message}")
        } catch (e: ServerResponseException) {
            println("服务器响应异常: ${e.message}")
        }
    }
    
    • ClientRequestException用于捕获请求过程中的异常,比如网络连接问题。
    • ServerResponseException用于捕获服务器返回的错误状态码(如404, 500等)相关的异常。