【问题标题】:How to get status code of HttpCall with Ktor and kotlinx serialization如何使用 Ktor 和 kotlinx 序列化获取 HttpCall 的状态码
【发布时间】:2020-08-19 09:03:35
【问题描述】:

我想弄清楚如何用Ktor检查http请求的http状态码

我有一个像这样的简单 GET 请求,其中包含一个 HttpResponseObject,它保存服务器返回的数据以及我控制的任何错误服务器端

val response:HttpResponseObject<MyObject> = client.get<HttpResponseObject<MyObject>>(url)

现在我还需要检查的是服务器是否抛出了未处理的异常或身份验证异常。在这些情况下,服务器不会返回任何内容,并且会返回状态码 500 或 401 错误。

我看到文档你可以通过类似这样的方式获得完整的 http 响应

val response:HttpResponse client.get(url)

但是如何丢失我的序列化数据回来,我找不到任何关于如何从 HttpResponse 对象序列化它的示例。

有人有什么建议吗?有没有办法从我的第一个示例中获取 http 状态代码?

【问题讨论】:

    标签: ktor kotlinx.serialization


    【解决方案1】:

    您可以尝试使用以下代码获取状态代码: val response = client.get&lt;HttpResponse&gt;(url) 之后,要从响应中获取字节并对其进行序列化,您可以尝试使用 val bytes: ByteArray = response.readBytes()

    您可以在此处找到完整的文档: https://ktor.io/clients/http-client/quick-start/responses.html

    【讨论】:

    • 是的,但是我如何将数据反序列化到我的对象中?
    • 视情况而定。如果状态码以纯文本形式返回,您只需使用 utf-8 或 ASCII 解码字节并将字符串复制到您的类中。
    • 进一步看 HttpResponse 已弃用此 api.ktor.io/1.3.2/io.ktor.client.statement/-http-response/…,它只有一个 ByteReadChannel
    【解决方案2】:

    我最终做的是使用HttpClientConfig 中的HttpResponseValidator 来捕获状态代码然后抛出异常

    HttpResponseValidator{
    
                validateResponse { response: HttpResponse ->
                    val statusCode = response.status.value
                    when (statusCode) {
                        in 300..399 -> throw RedirectResponseException(response)
                        in 400..499 -> throw ClientRequestException(response)
                        in 500..599 -> throw ServerResponseException(response)
                    }
    
                    if (statusCode >= 600) {
                        throw ResponseException(response)
                    }
                }
            }
    

    通过这样做,我能够通过我的自定义对象将错误传递回 UI

    private suspend fun getCurrentWeatherForUrl(url:String, callback: (HttpResponseObject<MyObject>?) -> Unit){
            var response:HttpResponseObject<MyObject>? = null
            response = try{
                client.get<HttpResponseObject<MyObject>>(url){
                    header("Authorization", "Bearer $authKey")
                }
            }catch (e:Exception){
                HttpResponseObject(null, e.toString())
            }
    
            callback(response)
        }
    

    您也可以使用HttpResponse.receive() 获取序列化对象和响应数据

    val response:HttpResponse = client.get(url)
    val myObject:MyObject = response.receive<MyObject>()
    

    【讨论】:

    • 什么是 HttpResponseObject?
    猜你喜欢
    • 2019-05-02
    • 2020-03-09
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 2020-11-20
    • 2020-12-05
    相关资源
    最近更新 更多