본문 바로가기

Android/기타

[Android] Retrofit2 Converter를 커스텀 해보기

반응형

Android Retrofit2를 사용하면서 GsonConverterFactory를 업무에도 이용하고 사이드 프로젝트에도 이용하고 있다. 하지만 업무 중에 문제가 발생하였는데 200번대(성공일 때)에서 status code로만(ResponseBody가 비어있을 때) 로직을 처리할 경우에 문제가 되었다.

 

에러의 원인은 ResponseBody의 파싱 에러였는데 GsonConverterFactory에서는 응답 성공일 때 무조건 ResponseBody를 Gson으로 파싱하게끔 되어 있어서 그런 것이 원인이었다. 그래서 직접 만들기로 한 Converter에서는 파싱 에러일 때 body의 Length가 0인 경우 null을 return하도록 수정하였다.

 

import androidx.annotation.Nullable;

import com.google.gson.Gson;
import com.google.gson.JsonIOException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;

import java.io.IOException;

import okhttp3.ResponseBody;
import retrofit2.Converter;

final class CustomResponseBodyConverterFactory<T> implements Converter<ResponseBody, T> {
    private final Gson mGson;
    private final TypeAdapter<T> mAdapter;

    public CustomResponseBodyConverterFactory(Gson gson, TypeAdapter<T> adapter) {
        mGson = gson;
        mAdapter = adapter;
    }

    @Nullable
    @Override
    public T convert(ResponseBody value) throws IOException {
        try {
            JsonReader jsonReader = mGson.newJsonReader(value.charStream());
            T result = mAdapter.read(jsonReader);
            if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
                throw new JsonIOException("JSON document was not fully consumed.");
            }
            return result;
        } catch (IOException e) {
            if (value.contentLength() == 0) {
                return null;
            }

            throw e;
        } finally {
            value.close();
        }
    }
}

 

위의 코드의 convert 부분을 살펴보자면 다음과 같다.

- try 부분은 json을 정상적으로 파싱한 경우

- catch 부분은 json 파싱 에러인 경우

 

200일 때 ResponseBody가 없어서 문제가 되는 부분은 catch인 경우인데 GsonConverterFactory 안에 있는 클래스에서는 이 부분을 파싱 에러를 내고 끝내버린다.

따라서 catch로 잡는데 이 때 진짜 응답 내용이 있을 수가 있으므로 정상적인 경우라고 생각하는 ContentLength가 0일 때만 null을 리턴하고 정상적으로 끝내주면 된다.

 

ConverterFactory에 필요한 3개의 파일은 다음 저장소에 올렸다.(추후 정리할 수도 있음)

github.com/masonljh/android_practice_sample/tree/main

 

그 외의 ConverterFactory와 RequestBodyConverterFactory는 GsonConverterFactory에 있는 것과 동일하게 구현하면 된다.
github.com/square/retrofit/tree/master/retrofit-converters/gson/src/main/java/retrofit2/converter/gson

 

square/retrofit

A type-safe HTTP client for Android and the JVM. Contribute to square/retrofit development by creating an account on GitHub.

github.com

반응형