티스토리 뷰
[안드로이드] Retrofit2에서 response.code() == 404 일 때, response.body() == null 나오는 경우
weekyear 2021. 4. 27. 01:06결론
긴 글 읽기 귀찮으신 분들을 위해 먼저 결론부터 말씀드리겠습니다.
response.code() Integer 값이 200 미만이거나 300이상 혹은 204나 205일 경우에는 response.body()는 null이 되어서 백엔드 서버에서 response body에 값을 보내주더라도 사용할 수 없습니다.
서론
이 글은 httpStatus 코드가 404일 때, 백엔드에서 보내주는 response body를 어떻게든 활용해보려는 새싹 개발자의 발버둥을 담은 글입니다.
상황
1. 백엔드 서버에 API 요청을 보냈을 경우, status가 200으로 올 때나 404로 올 때나 onResponse()가 호출된다.
call.enqueue(object : Callback<CustomResponse> {
override fun onResponse(call: Call<CustomResponse>, response: Response<CustomResponse>) {
// response.code()가 200일 때나 404일 때나 onResponse()가 호출된다.
if(response.isSuccessful()) {
// do something
}
else {
...
}
}
override fun onFailure(call: Call<CustomResponse>, t: Throwable) {
...
}
})
2. 백엔드 서버에서 해당 data를 찾지 못 할 경우 다음과 같은 형식의 데이터가 response body에 담겨져서 온다.
{
"status": 404,
"error": "Entity Not Found",
"code": "C003",
"message": "Cannot find User where email=jwnsgus@gmail.com"
}
3. response body의 데이터를 활용해서 분기 처리하여 성공했을 때 동작과 실패했을 때 동작을 지정해주려고 하였다.
...
override fun onResponse(call: Call<CustomResponse>, response: Response<CustomResponse>) {
when (response.body()?.status) {
"200" -> onSuccess()
"404" -> onFailure()
}
}
...
문제
response.code()가 200일 때는 정상 동작하였으나 404일 때는 response.body()가 항상 null이 되어서 response.body()를 활용할 수 없었다.
시행 착오
response.code()가 200일 때와 404일 때의 Json 데이터 형식이 달라서 그런 것일까 싶어서 httpStatus 코드에 따라 데이터 형식을 받는 방법을 달리 해주는 방법을 찾아보았다.
결과적으로는 문제의 해결책이 되지 않았지만 추후에 활용할 수 있는 공부 내용인 것 같아서 참고하였던 글 링크만 여기에 남기기로 하였다.
해결(?)
해결이라고 하기에는 민망한 것이 Retrofit2 라이브러리를 그대로 사용하는 한 404일 때, response.body()를 사용할 수 없다는 것을 알아가는 과정이었다.
Retrofit2의 라이브러리에서 OkHttpCall.java 파일에서 okhttp3의 Response를 Retrofit2의 Response타입으로 반환하는 parseResponse() 메서드를 천천히 보고 안 되는 이유를 알았다.
(나중에 기회가 된다면 404일 때도 response.body()를 활용할 수 있게 PullRequest도 진행해보고 싶다.)
위 결론에서 말했다시피
response.code() Integer 값이 200 미만이거나 300이상 혹은 204나 205일 경우에는 response.body()는 null이 되어서 백엔드 서버에서 response body에 값을 보내주더라도 사용할 수 없었다.
최종 코드
결국은 response.body()를 활용하지 않는 선에서 response.code()만으로 분기 처리해서 코드를 작성하게 됐다.
call.enqueue(object : Callback<CustomResponse> {
override fun onResponse(call: Call<CustomResponse>, response: Response<CustomResponse>) {
if(response.isSuccessful()) {
// do something
}
else {
when (response.code()) {
404 -> onFailure()
}
}
}
override fun onFailure(call: Call<CustomResponse>, t: Throwable) {
onFailure()
}
})
하지만, 같은 HttpStatus 코드에서는 어떻게 분기처리를 해야하는가...하는 문제가 남아있는데 지금 다른 구현이 바빠 잠시 미뤄두고 나중에 새롭게 구현해야 할 때 다시 다뤄보도록 할 것이다.
'Programming > 안드로이드(Android)' 카테고리의 다른 글
[안드로이드] Waiting For Debugger가 계속 뜨고 앱이 시작되지 않을 때 (0) | 2021.04.30 |
---|---|
[안드로이드] 갤러리(Gallery)의 Image uri를 가져오고 실제 기기의 저장 주소로 변환하는 법 (0) | 2021.04.27 |
[안드로이드] Android GoogleSignIn API error : statusCode 0, Status{statusCode=NETWORK_ERROR, resolution=null} (0) | 2021.04.26 |
[Android] View Binding, Activity에서와 Fragment에서 왜 구현 방법이 다를까? (0) | 2021.04.17 |
[Android] missing feature: WATCH (0) | 2021.04.16 |