在配置Retrofit 的时候,有如下方法
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(StringConverterFactory.create())
.addConverterFactory方法为添加相应结果解析器,存放于Retrofit.Builder类的converterFactories集合中。从Builder的构造方法可以看出创建Builder的时候会自动添加一个默认的ConvertFactory,我们也可以调用多次addConverterFactory添加多个ConvertFactory,处理结果的时候会按添加顺序优先匹配,一旦匹配上前面的,就丢弃后面的,当然我们能添加自己定义的ConvertFactory只要继承Converter.Factory,
在 Retrofit类中默认加了BuiltInConverters(593-603行),
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
在BuiltInConverters 中对ResponseBody和Void类型进行了转换处理
final class BuiltInConverters extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
...
经过测试,当自定义ConverterFactory时,在 responseBodyConverter 方法中,return null,才会执行下一个解析器,抛出异常和进行处理,不会执行到下一个解析器
当使用GsonConverterFactory,后面的解析器不会执行(因为GsonConverterFactory能对任何数据都可以进行转换(最多转换异常嘛))
假如自定义StringConverterFactory,而且还想要执行GsonConverterFactory,必须这样写
.addConverterFactory(StringConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
并且在StringConverterFactory的responseBodyConverter方法中进行处理
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
Log.e("StringConverter","action");
if (type == String.class){
return new StringConverter();
}else{
// throw new NullPointerException("type != String");
return null;
}
// return null;
}
下面是StringConverterFactory 代码
public final class StringConverterFactory extends Converter.Factory{
public static StringConverterFactory create() {
return new StringConverterFactory();
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
Log.e("StringConverter","action");
if (type == String.class){
return new StringConverter();
}else{
// throw new NullPointerException("type != String");
return null;
}
// return null;
}
@Nullable
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return new StringRequestBodyConverter();
}
}
public final class StringConverter implements Converter<ResponseBody,String> {
public StringConverter() {
}
@Override
public String convert(ResponseBody value) throws IOException {
try {
Log.e("String Converter",value.toString());
return value.string();
}finally {
value.close();
}
}
}
public class StringRequestBodyConverter implements Converter<String, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
private static final Charset UTF_8 = Charset.forName("UTF-8");
public StringRequestBodyConverter() {
}
@Override
public RequestBody convert(String value) throws IOException {
Buffer buffer = new Buffer();
Writer writer = new OutputStreamWriter(buffer.outputStream(),UTF_8);
writer.write(value);
writer.close();
return RequestBody.create(MEDIA_TYPE,buffer.readByteString());
}
}
参考文章
Retrofit的使用与深入学习
Retrofit详解(一)(Retrofit创建过程)
Retrofit自定义Converter之StringConverterFactory
下面是关于异常处理的:
Retrofit+RxJava 优雅的处理服务器返回异常、错误
Retrofit统一处理服务器返回参数
关于Retrofit返回错误信息的统一解决办法