retrofit 2.6.1源码解析(二)converter

本文详细介绍了Retrofit框架如何使用Gson进行数据转换,包括GsonConverterFactory的创建及其实现的Converter.Factory接口,GsonRequestBodyConverter和GsonResponseBodyConverter的具体作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


Retrofit支持Gson,进行数据转换

引入,很轻量呀,就3个类

  • GsonConverterFactory,用于构建GsonConverter的工厂类

  • GsonRequestBodyConverter,将Java对象转换为RequestBody

  • GsonResponseBodyConverter,将ResponseBody转换为Java对象

implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
 Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.github.com/")
                .addConverterFactory(GsonConverterFactory.create(new Gson())) //增加对Gson库的支持
                .build();

在这里插入图片描述

构建responseConverter

第一篇中,getServiceMethod()中,会构造 responseConver对象,假使我们注册了GsonConverterFactory

  • 通过retrofit的converterFactories去取factory,默认下标从0开始

  • Converter.Factory是个抽象类,有两个抽象方法,分别提供requestBodyConverter,ResponseBodyConverter

  • GsonConverterFactory实现了Converter.Factory,分别提供GsonRequestBodyConverter,GsonResponseBodyConverter

//HttpServiceMethod.java

 //得到responseConver对象,使用自定义,或内置的
Type responseType = callAdapter.responseType();
Converter<ResponseBody, ResponseT> responseConverter
		 = createResponseConverter(retrofit, method, responseType);

private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
      Retrofit retrofit, Method method, Type responseType) {
    Annotation[] annotations = method.getAnnotations();
    try {
      return retrofit.responseBodyConverter(responseType, annotations);
    } catch (RuntimeException e) { // Wide exception range because factories are user code.
      throw methodError(method, e, "Unable to create converter for %s", responseType);
    }
  }
//Retrofit.java
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
    return nextResponseBodyConverter(null, type, annotations);
  }

  public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
      @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
 
    int start = converterFactories.indexOf(skipPast) + 1; //start从0开始
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      Converter<ResponseBody, ?> converter =
          converterFactories.get(i).responseBodyConverter(type, annotations, this);
        return (Converter<ResponseBody, T>) converter;
    }
  }

Retrofit2.6.1包中的Converter接口

public interface Converter<F, T> {
  @Nullable T convert(F value) throws IOException;

  /** Creates {@link Converter} instances based on a type and target usage. */
  abstract class Factory {
   
   //responseBody
    public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
        Annotation[] annotations, Retrofit retrofit) {
      return null;
    }

    public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
        Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
      return null;
    }
  }
}

GsonConverterFactory

  • GsonConverterFactory 继承了Converter.Factory,工厂类

  • responseBodyConverter() 返回GsonResponseBodyConverter对象,

  • requestBodyConverter() 返回requestBodyConverter对象

TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));

首先都通过T的类对象,得到TypeAdapter对象,默认是通过反射来实现的。

Gson 2.8.5源码解析(一)

public final class GsonConverterFactory extends Converter.Factory {
  
  //提供一个统一的Gson对象
  public static GsonConverterFactory create() {
    return create(new Gson());
  }
//返回一个GsonConverterFactory
  public static GsonConverterFactory create(Gson gson) {
    return new GsonConverterFactory(gson);
  }

  private final Gson gson;

  private GsonConverterFactory(Gson gson) {
    this.gson = gson;
  }

//将ResponseBody转换为Java对象
  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); 
    return new GsonResponseBodyConverter<>(gson, adapter);
  }

  //将Java对象转换为RequestBody
  @Override
  public Converter<?, RequestBody> requestBodyConverter(Type type,
      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonRequestBodyConverter<>(gson, adapter);
  }
}

GsonRequestBodyConverter

将Java对象转换为RequestBody

final class GsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
  private static final MediaType MEDIA_TYPE = MediaType.get("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());
  }
}

GsonResponseBodyConverter

将ResponseBody转换为Java对象

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 {
      T result = adapter.read(jsonReader);
      if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
        throw new JsonIOException("JSON document was not fully consumed.");
      }
      return result;
    } finally {
      value.close();
    }
  }
}

总结:

requestConverter(将java对象转换为requestBody):

  • 在RequestFactory类中,retrofit.requestBodyConverter()得到Converter<?, RequestBody>对象

  • 通过retrofit遍历converterFactories,factory.requestBodyConvert(),返回converter对象

     如果是GsonConverterFactory返回的GsonRequestBodyConverter
     java对象,序列化为Json字符串,字符串通过RequestBody.create()转换为RequestBody对象
    

responseConverter(将ResponseBody转换为java对象):

  • 在HttpServiceMethod类中,retrofit.responseBodyConverter()得到Converter<ResponseBody, ?>对象

  • 通过retrofit遍历converterFactories,factory.responseBodyConverter(),返回converter对象

     如果是GsonConverterFactory返回的GsonResponseBodyConverter
     gson.newJsonReader(value.charStream()),得到jsonReader,typeAdapter.read(jsonReader)返回T
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值