Skip to content

응답 검증

기본적으로 Ktor HTTP 클라이언트는 HTTP 상태 코드에 따라 응답을 검증하지 않습니다. 필요한 경우, 다음과 같은 전략을 사용하여 응답 검증을 활성화하고 커스텀할 수 있습니다.

기본 검증 활성화

Ktor에서는 expectSuccess 속성을 true로 설정하여 기본 검증을 활성화할 수 있습니다. 활성화하면 클라이언트는 성공적이지 않은 HTTP 상태 코드를 가진 모든 응답에 대해 예외를 발생시킵니다.

클라이언트 설정에서 이 동작을 전역적으로 활성화할 수 있습니다:

kotlin
import io.ktor.client.*
import io.ktor.client.engine.cio.*

val client = HttpClient(CIO) {
    expectSuccess = true
}

또는 요청별로 expectSuccess를 활성화할 수도 있습니다. 이 경우 2xx가 아닌 에러 응답에 대해 다음과 같은 예외가 발생합니다:

커스텀 검증

기본 검증 동작 외에도, HttpCallValidator 플러그인을 사용하여 커스텀 응답 검증 로직을 정의할 수 있습니다. 이를 통해 성공적인(2xx) 응답을 검증하거나 2xx가 아닌 응답이 처리되는 방식을 오버라이드할 수 있습니다.

HttpCallValidator를 설치하려면 클라이언트 설정 블록 내에서 HttpResponseValidator 함수를 호출하세요:

kotlin
val client = HttpClient(CIO) {
    HttpResponseValidator {
        // ...
    }
}

2xx 응답 검증

기본 검증은 2xx가 아닌 응답에 대해서만 예외를 발생시킵니다. 애플리케이션에 더 엄격한 검증이 필요한 경우, validateResponse {} 함수를 사용하여 성공적인 응답을 검증할 수 있습니다.

다음 예제에서 서버는 에러 페이로드가 JSON 형식으로 포함된 2xx 응답을 반환합니다. validateResponse {} 블록은 응답 본문을 검사하고 에러가 감지되면 커스텀 예외를 발생시킵니다:

kotlin
val client = HttpClient(CIO) {
    install(ContentNegotiation) { json() }
    HttpResponseValidator {
        validateResponse { response ->
            val error: Error = response.body()
            if (error.code != 0) {
                throw CustomResponseException(response, "Code: ${error.code}, message: ${error.message}")
            }
        }
    }
}

전체 예제는 client-validate-2xx-response를 참조하세요.

2xx가 아닌 예외 처리

2xx가 아닌 응답 예외가 처리되는 방식을 커스텀하려면 handleResponseExceptionWithRequest {} 함수를 사용하세요.

다음 예제에서 클라이언트는 404 Not Found 응답에 대해 기본 ClientRequestException 대신 커스텀 MissingPageException을 발생시킵니다:

kotlin
class MissingPageException(response: HttpResponse, cachedResponseText: String) :
    ResponseException(response, cachedResponseText) {
    override val message: String = "Missing page: ${response.call.request.url}. " +
            "Status: ${response.status}."
}

fun main() {
    val client = HttpClient(CIO) {
        expectSuccess = true
        HttpResponseValidator {
            handleResponseExceptionWithRequest { exception, request ->
                val clientException = exception as? ClientRequestException ?: return@handleResponseExceptionWithRequest
                val exceptionResponse = clientException.response
                if (exceptionResponse.status == HttpStatusCode.NotFound) {
                    val exceptionResponseText = exceptionResponse.bodyAsText()
                    throw MissingPageException(exceptionResponse, exceptionResponseText)
                }
            }
        }
    }

    runBlocking {
        val httpResponse: HttpResponse = try {
            client.get("https://ktor.io/docs/missing-page.html")
        } catch (cause: ResponseException) {
            println(cause)
            cause.response
        }
    }
}

전체 예제는 client-validate-non-2xx-response를 참조하세요.