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對象,默認是通過反射來實現的。
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