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 |