retrofit null & String response 처리(EOFException, JsonIOException)

정용우·2023년 8월 31일

문제 사항


기본적으로 retrofit 통신 response를 gson으로 변환하여 결과를 받는 방식을 사용하였으나 response가 null이거나 String일 때 따로 설정을 해주지 않으면 오류를 뱉어낸다.

null일 경우 EOFException을, String의 경우 JsonIOException에러를 호출하는데 해결하기 위해서는 ConverterFactory를 추가해 주어야 한다.

class NullOnEmptyConverterFactory : Converter.Factory() {
    fun converterFactory() = this
    override fun responseBodyConverter(type: Type, annotations: Array<out Annotation>, retrofit: Retrofit) = object : Converter<ResponseBody, Any?> {
        val nextResponseBodyConverter = retrofit.nextResponseBodyConverter<Any?>(converterFactory(), type, annotations)
        override fun convert(value: ResponseBody) = if (value.contentLength() != 0L) nextResponseBodyConverter.convert(value) else null
    }
}
retrofit = Retrofit.Builder()
            .baseUrl(API_URL)
            .client(client)
            .addConverterFactory(NullOnEmptyConverterFactory())
            .addConverterFactory(ScalarsConverterFactory.create())
			.addConverterFactory(GsonConverterFactory.create(gson))
            .build()

생성해 준 NullOnEmptyConverterFactory가 null값에 대한 처리를 하고 retrofit2에서 제공하는 ScalarsConverterFactory가 String값에 대한 처리를 한다.

참고


ScalarsConverterFactory 내부 코드가 다음과 같은데, String뿐만 아니라 대부분의 primitive type에도 대응하는 듯하다.

@Override public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    if (type == String.class
        || type == boolean.class
        || type == Boolean.class
        || type == byte.class
        || type == Byte.class
        || type == char.class
        || type == Character.class
        || type == double.class
        || type == Double.class
        || type == float.class
        || type == Float.class
        || type == int.class
        || type == Integer.class
        || type == long.class
        || type == Long.class
        || type == short.class
        || type == Short.class) {
      return ScalarRequestBodyConverter.INSTANCE;
    }
    return null;
  }

0개의 댓글