이번 게시물은 백엔드 개발자와 협업을 하던 중 새로운 것을 알게되어서 이 내용을 정리하려 한다.
이번 내용은 Retrofit에 관한 내용으로 Retrofit도 나름 공식문서가 있겠지만, 공식문서를 확인하지 않고 로그를 찍고 주변사람들에게 물어보면서 해답을 얻었다.
1. status code
Retrofit에서 status code는 우리가 흔히 알고 있는 HTTP code를 생각하면 된다.
기존에 나는 이 status code가 '통신'이 제대로 되는지 안되는지에 대한 자동으로 지정되는 코드값인줄 알았는데, 이번에 서버에서 이 코드를 지정한 값으로 반환할 수 있다는 것을 알게 되었다.
전에 다른 백엔드 개발자와 협업했을 때는 status code를 무조건 200으로 설정하고, 그 후에 response body 안에 값을 넣었었다.
그래서 이 부분에 대해서 알게 되고, 주변에 물어보니 일반적으로는 status code를 사용해서 결과를 알려준다고 한다.
1
2
3
4
5
6
7
8
9
|
Response<>.code() // 이렇게 호출할 수 있고,
if( Response<>.code() == 200){ // 이런식으로 사용한다.
}
else{
}
|
cs |
2. HttpLoggingIntercepter
그런데, Response.code가 400이나 500으로 지정되면 response안의 body를 읽어올 수 없다.
body가 null값으로 들어오기 때문이다.
이런 문제때문에 하루종일 삽질을 했었고, 솔직히 백엔드 개발자가 코드를 잘못 설계한줄 알았었다......
내가 못찾은거였지만 하루종일 구글링을 해봐도 답을 찾을 수 없었다.
그러던 와중에 HttpLoggingIntercepter를 알게 되었다.
HttpLoggingIntercepter는 Http 통신하는 과정을 Log로 찍어주는 역할을 한다.
이를 사용하면 try/catch문에서 잡히지 않는 Http 통신 과정에서의 에러를 로그로 확인할 수 있다.
HttpLoggingIntercepter는 먼저 dependencies를 추가한 다음,
1
2
3
4
5
6
7
8
9
10
11
|
dependencies {
...
// Retrofit, GsonConverter, Okhttp
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
...
}
|
cs |
아래와 같이 사용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
object ApiClient { // 기존의 Retrofit
private val apiInterface: ApiInterface
val retrofit:Retrofit
val baseUrl: String = ""
var clientBuilder = OkHttpClient.Builder() // 여기랑
var loggingInterceptor = HttpLoggingInterceptor() // 여기,
init {
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
clientBuilder.addInterceptor(loggingInterceptor)
retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(clientBuilder.build()) // 여기를 추가해주면 된다.
.build()
apiInterface = retrofit.create(ApiInterface::class.java)
}
fun getApiInterface(): ApiInterface = apiInterface
}
|
cs |
3. Errorbody
로그를 찍어보니, 응답이 포스트맨에서 찍은대로 그대로 들어오긴 했으나, 여전히 response의 body()에는 null 값이 들어있었다.
혼자 고민해보고 로그에는 유효한 값이 찍혔지만, body()에 null값이 있다는 것은 다른 어딘가에서 유효한 데이터를 갖고 있다는 결론을 내렸다.
구글링으로 답을 못찾고 혼자 삽질하다가 결국 지인의 도움으로 errorbody라는것을 알게 되었다.
1
2
3
4
5
6
7
8
9
|
Response<>.code()
if( Response<>.code() == 200){
}
else{ // Error가 발생할 때(status code가 200이 아닐 때)
Response<>.errorBody() // 이렇게 호출할 수 있다.
}
|
cs |
우리가 Response의 Body를 사용할 때는 Retrofit 객체를 만들 때 등록해준 GsonConverter가 자동으로 Java 또는 Kotlin 코드로 변환해준다.
ErrorBody는 별도로 컨버팅 과정을 거쳐줘야 Body 처럼 사용할 수 있다.
ErrorBody의 컨버팅은 아래처럼 해주면 된다.
1
2
3
4
5
|
object NetworkUtil {
fun getErrorResponse(errorBody: ResponseBody): ErrorResponse {
return ApiClient.retrofit.responseBodyConverter<ErrorResponse>(ErrorResponse::class.java, ErrorResponse::class.java.annotations).convert(errorBody)!!
}
}
|
cs |
4. Header
Body와 ErrorBody를 사용하면서 백엔드 개발자분이 토큰이나 권한에 대한 값을 Header로 넘겨주었다.
Retrofit을 사용할 때 전에는 Body만 사용했는데, 이번에 ErrorBody를 알게 되면서 Header도 유효한 값을 사용할 수 있게 되었다.
Header는 아래처럼 사용하면 된다!
1
2
|
Log.e("Header Data : ", response.headers().get("Authorization").toString())
|
cs |
'Legacy' 카테고리의 다른 글
[안드로이드 스튜디오 독학#51] Room + Repository + ViewModel + Application (0) | 2022.02.19 |
---|---|
[안드로이드 스튜디오 정리#18] Room (0) | 2022.02.18 |
[안드로이드 스튜디오 독학#50] Navigation (0) | 2022.02.08 |
[안드로이드 스튜디오 독학#49] BaseActivity, BaseFragment, BaseViewModel (0) | 2022.02.06 |
[안드로이드 스튜디오 정리#16] Coroutine (0) | 2022.02.04 |