본문 바로가기

안드로이드/Network

OkHttp

HTTP 클라이언트 라이브러리로, HTTP 요청, 응답, 캐싱, 커넥션 풀과 같은 저수준 작업을 처리한다.

 

OkHttp는 Android 5.0 (API 21) 이상 및 JAVA 8 이상에서 동작하며, Okio와 Kotlin 표준 라이브러리를 사용한다.

 

특징

  • HTTP/2의 경우 동일한 호스트에 대한 모든 요청이 동일한 소켓을 공유할 수 있다.

  • Connection Pooling: 요청마다 새로 연결하지 않고 Connection Pool 기능을 이용하여 동일한 URL의 연결을 Pooling하여 재사용한다. (HTTP/2가 아닌 경우)

  • Transparent GZIP: 응답 데이터를 압축하여 네트워크 트래픽을 줄여준다.
    • 서버에 압축된 콘텐츠를 허용한다는 Accept-Encoding: gzip 를 헤더에 담아보내면 서버에서는 이를 확인하고 압축하여 전송한다.
    • 응답 받은 데이터 헤더에 Content-Encoding: gzip이 있다면 압축을 해제하고 아니면 넘어온 Response를 반환한다.
    • OkHttp에서는 이 헤더를 자동으로 담아 보내기 때문에 따로 설정하지 않아도 되지만, 서버에 전송하는 데이터를 압축할 경우에는 따로 Interceptor를 통해 정의해줘야 한다.
  • Response Caching: 동일한 요청에 대해 로컬 캐싱으로 네트워크 트래픽을 최소화 한다.

  • 일반적인 네트워크 연결 문제 발생 시 자동으로 복구

  • 보안: 최신 TLS 기능 지원
Connection Pool이란?
Connection 객체를 미리 생성, 연결이 필요한 경우 미리 생성한 Connection 객체를 사용하여 성능을 향상시킬 수 있다.

 

 

Interceptor

Interceptor는 요청 또는 응답을 중간에 가로채 추가적인 작업을 수행하는 기능으로 모니터링, 재작성, 재시도 등을 할 수 있다.

대표적으로 헤더를 추가하거나 로깅, 인증, 캐싱과 같은 작업들을 구현할 수 있다.

 

Logging Intercepter 예제

class LoggingInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()

        val t1 = System.nanoTime()
        logger.info(
            java.lang.String.format(
                "Sending request %s on %s%n%s",
                request.url, chain.connection(), request.headers
            )
        )

        val response = chain.proceed(request)

        val t2 = System.nanoTime()
        logger.info(
            String.format(
                "Received response for %s in %.1fms%n%s",
                response.request.url, (t2 - t1) / 1e6, response.headers
            )
        )

        return response
    }
}

 

OkHttp 사용 예제

1. getUrl

class OkHttpTest {
    private val okClient = OkHttpClient()
    fun getUrl(): String? {
        val request = Request.Builder()
            .url(ConnectApi.URL)
            .build()

        try {
            val response = okClient.newCall(request).execute()
            return response.body?.string()
        } catch (e: Exception) {
            return null
        }
    }
}

 

2. postToServer

class OkHttpTest {
    private val okClient = OkHttpClient()

    fun postToServer(json: String): String? {
        val body = json.toRequestBody(JSON)
        val request = Request.Builder()
            .url(ConnectApi.URL)
            .post(body)
            .build()

        try {
            val response = okClient.newCall(request).execute()
            return response.body?.string()
        } catch (e: Exception) {
            return null
        }
    }

    companion object {
        private val JSON = "application/json".toMediaType()
    }
}

 

3. Interceptor 등록

class OkHttpTest {
    fun loggingInterceptor() {
        val loggingClient = OkHttpClient.Builder()

        loggingClient
            .addInterceptor(LoggingInterceptor())
            .build()
        
        try {
            ...
        } catch (e: Exception){
            ...
        }
    }

    class LoggingInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val request = chain.request()

            val t1 = System.nanoTime()
            logger.info(
                java.lang.String.format(
                    "Sending request %s on %s%n%s",
                    request.url, chain.connection(), request.headers
                )
            )

            val response = chain.proceed(request)

            val t2 = System.nanoTime()
            logger.info(
                String.format(
                    "Received response for %s in %.1fms%n%s",
                    response.request.url, (t2 - t1) / 1e6, response.headers
                )
            )

            return response
        }
    } 
}

 


이와 같이 OkHttp는 다양한 기능을 제공하지만 URL에서의 쿼리를 직접 입력해야하며, 응답 데이터를 직접 Json 파싱하는 등 중복되거나 불편한 부분들이 여전히 존재한다.

'안드로이드 > Network' 카테고리의 다른 글

JSON Converter Library  (0) 2025.05.20
Retrofit  (0) 2025.05.15
HttpUrlConnection  (0) 2025.05.12
[안드로이드] 서버 통신 Retrofit2  (0) 2023.11.06