기본적으로 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;
}