[Android] Retrofit에서 2xx 응답 외 값 가져오기

양현진·2022년 3월 30일
0

Oh My Android

목록 보기
10/22
post-thumbnail

응답 성공 값이 resultCode가 3xx로 들어오는 경우, Retrofit과 Rx를 같이 사용할 때 2xx값이 아니면 바로 throw처리를 한다고 하여 도중에 값을 가로채오는 방법을 알아내 적어본다.

해당 문제가 있을 때 원래 Redirect된 응답은 변경된 주소를 주거나 변경된 주소로 값을 내준다고 한다. 실제로 코드상에선 에러지만 브라우저에 주소를 입력하면 원하는 값이 나왔다. 이리저리 생각하다가 httpLogginInterceptor로 응답값을 자세히 살펴보았고, 로그값에 원하는 값이 실려와 빼오는 노력을 기울였다. 전 프로젝트에서 Interceptor를 사용해봤기에 큰 시간낭비 없이 문제를 해결했었다.!

해당 문제를 해결하기전, 간단하게 Retrofit의 Interceptor를 알고 가보자.

Interceptor

'가로채는자'라는 뜻이며, 서버에서 클라이언트로 또는 클라이언트에서 서버로 값이 이동할 때, 해당 목적지에 도착하기전 값을
도중에 빼와 읽거나 수정할 수 있게 도와주는 놈이다.

느낌이 오듯이, 이번 해결법도 앱단에 도착하기전 Redirect된 값을 미리 빼와 Reponse을 조작하여 Rx의 Single로 전달하는 방법을 이용했다.

해결

OkHttp의 HttpLoggingInterceptor를 NetworkInterceptor부분에 추가하여 서버에서 Retrofit으로 답이 오기 전 미리 값을 빼오고 앱에 도착할 Response를 커스텀하여 원하는 응답으로 바꾸고 Retrofit이 적절히 받을 수 있게 status code를 200변경함.

override fun intercept(chain: Interceptor.Chain): Response {
        val response = chain.proceed(chain.request())

        if (url != null) {
            return response.newBuilder()
                .code(200)
                .body(url!!.toResponseBody())
                .build()
        }

        return response.newBuilder()
            .code(502)
            .message("CustomInterceptor: There is not value starting with \"https:\"")
            .build()
    }

    fun httpLoggingInterceptor(): HttpLoggingInterceptor {
        val interceptor = HttpLoggingInterceptor { message ->
            if (message.startsWith("\"https:"))
                url = message
        }
        return interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
}

여러 네트워크 로그중 내가 원하는 값을 가져오기 위해선 파싱을 해야하는데, Url주소값이 필요하여 “https: 로 시작하는 값을 startWith를 이용하여 빼내온다. 그리고 Response값을 재정의하여 해당 링크값과 status code를 변경하여 앱 단에서 적절히 받아오게 한다. HttpLoggingInterceptor를 사용하기 위해선 gradle에 추가하여하 한다.

// OkHTTP
implementation("com.squareup.okhttp3:logging-interceptor:$okhttp_version")

intercept 클래스에서 code를 2xx로 바꾸지 않으면 똑같이 에러가 나니 필히 바꿔야 한다.

profile
Android Developer

0개의 댓글