https://kotlinlang.org logo
#ktor
Title
# ktor
g

Gyuhyeon

02/19/2020, 9:07 AM
Is there a way to
.receive()
response using ktor client to access
HttpResponse
while also accessing the response body as a type? What I mean is,
Copy code
ktorClient.request<HttpStatement> {...}.receive<HttpResponse>()
seems to be one way to receive responses while
Copy code
ktorClient.request<HttpStatement> {...}.receive<MyJsonModel>()
seems to be a way to receive the body as a predefined data class. However, due to needs in highly customized logging and whatnot, I need a way to access HttpResponse along with parsing it into MyJsonModel. What I would've preferred is something along the lines of
Copy code
val response = ktorClient.request<HttpStatement> {...}.receive<HttpResponse>()
// do things with response and then...
return response.parseBodyAs(MyJsonModel::class.java)
but there doesn't seem to be a way to do so. Do I have to parse myself using serializers manually if I decide to receive as
HttpResponse
?
c

cy

02/19/2020, 12:37 PM
Can't you call the recieve function with a model type on a response?
g

Gyuhyeon

02/20/2020, 1:26 AM
that would generate an error that says it's a duplicate receive call - .receive() can only be called once per request as far as I can see. However, I got around this problem by either parsing it manually with ObjectMapper() or solving it entirely differently so that I don't need the HttpStatement/HttpResponse access in the first place.
j

Julius

02/20/2020, 9:55 AM
I use this:
Copy code
var call: HttpClientCall? = null

                try {
                    call = clientEngine.call {
                        url(requestUrl)
                        method = <http://HttpMethod.Post|HttpMethod.Post>
                        for (entry in parameters) {
                            parameter(entry.key, entry.value)
                        }
                    }

                    Logger.d(LOG_TAG, "$requestName sending new Request: ${call.request.url}")
                    val received = call.receive<JsonObject>()
                    Logger.d(LOG_TAG, "$requestName Response success [statusCode: ${call.response.status}]: \n$received")

                    serverResponse = handler.createResponse(received)
                    handler.onWorkerSuccess(serverResponse!!)
                } catch (err: Throwable) {
                    Logger.e(LOG_TAG, "$requestName Request failed: $err")

                    if (err is ResponseException) {
                        val received = err.response.receive<JsonObject>()
                        if (call != null) {
                            Logger.d(LOG_TAG, "$requestName ERROR got response [statusCode: ${call.response.status}]: \n[$err]\n$received")
                        }

                        errorResponse = ErrorResponse(received)
                        handler.onWorkerErrorResponse(errorResponse!!)

                    } else {
                        offlineException = OfflineException(err.message, err)
                    }
                }
3 Views