Retrofit源码学习笔记(3)-Converters解析

来源:互联网 发布:淘宝摄影师怎么接活 编辑:程序博客网 时间:2024/05/21 19:43

什么是Converters?
默认的,Retrofit只能将HTTP返回对象转化为okhttp的Responsebody,同时它也只能处理okhttp的RequestBody,这显然无法满足我们的要求,因此就出现了Converters,它的作用在于能加java类型转换为RquestBody对象,也能将Responsebody实体转化为Java对象。

和CallAdapter相似,Retrofit的Converters也采用了工厂模式,从而可以使我们自定义我们想要的Converters。
Converter的源码:

public interface Converter<F, T> {  T convert(F value) throws IOException;  abstract class Factory {    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,        Retrofit retrofit) {      return null;    }    public Converter<?, RequestBody> requestBodyConverter(Type type,        Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {      return null;    }    public Converter<?, String> stringConverter(Type type, Annotation[] annotations,        Retrofit retrofit) {      return null;    }  }}

上面代码中,responseBodyConverter用于将请求返回的Responsebody对象转换为我们想要的java对象,requestBodyConverter用于将我们处理的java对象转换为requestBody请求体。stringConverter用于将java对象转化为String类型。

举个简单的栗子

比如,我们想通过retroift将一个简单网页的数据下下来,展示在webview上(这个用retorifit没啥好处,就是举个栗子),我们通过将返回的数据变为string类型,进行展示。
构建一个ResponseBodytoStringConverter:

public  class StringConver implements Converter<ResponseBody , String> {    public static final StringConver INSTANCE = new StringConver();    @Override    public String convert(ResponseBody value) throws IOException {        return value.string();    }}

构建一个工厂类

public class StringConverterFactory extends Converter.Factory {    public StringConverterFactory(){};    public static StringConverterFactory create() {        return new StringConverterFactory();    }    @Override    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {        return StringConver.INSTANCE;    }}

接口:

public interface CallStirngService {    @GET("2199295")    Call<String> CallStirngService();}

MainActivity

public class MainActivity extends AppCompatActivity {    public WebView WB;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        WB = (WebView) this.findViewById(R.id.wb);        Retrofit retrofit = new Retrofit.Builder()                .baseUrl("http://hw1287789687.iteye.com/blog/")                .addConverterFactory(StringConverterFactory.create())                .build();        CallStirngService repo = retrofit.create(CallStirngService.class);        Call<String> call = repo.CallStirngService();        call.enqueue(new Callback<String>() {                         @Override                         public void onResponse(Call<String> call, Response<String> response) {                            WB.loadData(response.body(),"text/html","UTF-8");                         }                         @Override                         public void onFailure(Call<String> call, Throwable t) {                         }                     }            );    }}

结果就是最后在WebWiew上能够展示我们想要的网页数据。

简单来说,Converter就是okhttp的输入输出格式,和我们想要的数据之间的一个转换器。Retrofit官方给出了许多的converter,用得最多的就是GsonConverFactory。
GsonRequestBodyConverter

final class GsonRequestBodyConverter<T> implements Converter<T, RequestBody> {  private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");  private static final Charset UTF_8 = Charset.forName("UTF-8");  private final Gson gson;  private final TypeAdapter<T> adapter;  GsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {    this.gson = gson;    this.adapter = adapter;  }  @Override public RequestBody convert(T value) throws IOException {    Buffer buffer = new Buffer();    Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);    JsonWriter jsonWriter = gson.newJsonWriter(writer);    adapter.write(jsonWriter, value);    jsonWriter.close();    return RequestBody.create(MEDIA_TYPE, buffer.readByteString());  }}
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {  private final Gson gson;  private final TypeAdapter<T> adapter;  GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {    this.gson = gson;    this.adapter = adapter;  }  @Override public T convert(ResponseBody value) throws IOException {    JsonReader jsonReader = gson.newJsonReader(value.charStream());    try {      return adapter.read(jsonReader);    } finally {      value.close();    }  }}

上诉代码的作用分别是将responseBody装换为json,和
将json转换为requestbody。我们也在可以在convert中进行额外的操作,比如安全验证等等,具体可以视开发情况而定。

0 0