GsonConverterFactory源码分析

  • 前言

    前面我们分析了Retrofit的源码,知道了GsonConverterFactory是如何和Retrofit结合起来的。

  • GsonRequestBodyConverter

    先看请求入参如何转换,即通过handlers[p].apply(requestBuilder, args[p])来解析参数,以ParameterHandler.Body为例:

    static final class Body extends ParameterHandler {
      private final Method method;
      private final int p;
      private final Converter converter;
    
      Body(Method method, int p, Converter converter) {
        this.method = method;
        this.p = p;
        this.converter = converter;
      }
    
      @Override
      void apply(RequestBuilder builder, @Nullable T value) {
        if (value == null) {
          throw Utils.parameterError(method, p, "Body parameter value must not be null.");
        }
        RequestBody body;
        try {
          body = converter.convert(value);
        } catch (IOException e) {
          throw Utils.parameterError(method, e, p, "Unable to convert " + value + " to RequestBody");
        }
        builder.setBody(body);
      }
    }
    

    调用converter.convert(value)生成body,看一下converter(GsonRequestBodyConverter)的convert:

    final class GsonRequestBodyConverter implements Converter {
      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 adapter;
    
      GsonRequestBodyConverter(Gson gson, TypeAdapter 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

    再来看返参转换,即通过OkHttpCall中execute调用的parseResponse(call.execute()):

    Response parseResponse(okhttp3.Response rawResponse) throws IOException {
      ResponseBody rawBody = rawResponse.body();
    
      // Remove the body's source (the only stateful object) so we can pass the response along.
      rawResponse =
          rawResponse
              .newBuilder()
              .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
              .build();
    
      int code = rawResponse.code();
      if (code < 200 || code >= 300) {
        try {
          // Buffer the entire body to avoid future I/O.
          ResponseBody bufferedBody = Utils.buffer(rawBody);
          return Response.error(bufferedBody, rawResponse);
        } finally {
          rawBody.close();
        }
      }
    
      if (code == 204 || code == 205) {
        rawBody.close();
        return Response.success(null, rawResponse);
      }
    
      ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
      try {
        T body = responseConverter.convert(catchingBody);
        return Response.success(body, rawResponse);
      } catch (RuntimeException e) {
        // If the underlying source threw an exception, propagate that rather than indicating it was
        // a runtime exception.
        catchingBody.throwIfCaught();
        throw e;
      }
    }
    

    调用responseConverter.convert(catchingBody)生成body,看一下responseConverter(GsonResponseBodyConverter)的convert:

    final class GsonResponseBodyConverter implements Converter {
      private final Gson gson;
      private final TypeAdapter adapter;
    
      GsonResponseBodyConverter(Gson gson, TypeAdapter 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();
        }
      }
    }
    
  • 源码分析

    可以看到不管是write还是read,都需要adapter去做,adapter是什么呢?回到构建它们的地方:

    @Override
    public Converter responseBodyConverter(
        Type type, Annotation[] annotations, Retrofit retrofit) {
      TypeAdapter adapter = gson.getAdapter(TypeToken.get(type));
      return new GsonResponseBodyConverter<>(gson, adapter);
    }
    
    @Override
    public Converter requestBodyConverter(
        Type type,
        Annotation[] parameterAnnotations,
        Annotation[] methodAnnotations,
        Retrofit retrofit) {
      TypeAdapter adapter = gson.getAdapter(TypeToken.get(type));
      return new GsonRequestBodyConverter<>(gson, adapter);
    }
    

    都是通过gson.getAdapter来获取adapter的,这里的type就是方法中每个参数的类型,TypeToken封装了一下:

    public static TypeToken get(Type type) {
      return new TypeToken(type);
    }
     

    看一下gson的getAdapter做了什么:

    public  TypeAdapter getAdapter(TypeToken type) {
      TypeAdapter cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
      if (cached != null) {
        return (TypeAdapter) cached;
      }
    
      Map, FutureTypeAdapter> threadCalls = calls.get();
      boolean requiresThreadLocalCleanup = false;
      if (threadCalls == null) {
        threadCalls = new HashMap, FutureTypeAdapter>();
        calls.set(threadCalls);
        requiresThreadLocalCleanup = true;
      }
    
      // the key and value type parameters always agree
      FutureTypeAdapter ongoingCall = (FutureTypeAdapter) threadCalls.get(type);
      if (ongoingCall != null) {
        return ongoingCall;
      }
    
      try {
        FutureTypeAdapter call = new FutureTypeAdapter();
        threadCalls.put(type, call);
    
        for (TypeAdapterFactory factory : factories) {
          TypeAdapter candidate = factory.create(this, type);
          if (candidate != null) {
            call.setDelegate(candidate);
            typeTokenCache.put(type, candidate);
            return candidate;
          }
        }
        throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
      } finally {
        threadCalls.remove(type);
    
        if (requiresThreadLocalCleanup) {
          calls.remove();
        }
      }
    }
    

    通过遍历factories调用factory.create(this, type)得到candidate,如果不为空就返回,那么factories从哪来的呢?在Gson的构造方法里得到答案:

    Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy,
        final Map> instanceCreators, boolean serializeNulls,
        boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
        boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
        LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
        int timeStyle, List builderFactories,
        List builderHierarchyFactories,
        List factoriesToBeAdded) {
      this.excluder = excluder;
      this.fieldNamingStrategy = fieldNamingStrategy;
      this.instanceCreators = instanceCreators;
      this.constructorConstructor = new ConstructorConstructor(instanceCreators);
      this.serializeNulls = serializeNulls;
      this.complexMapKeySerialization = complexMapKeySerialization;
      this.generateNonExecutableJson = generateNonExecutableGson;
      this.htmlSafe = htmlSafe;
      this.prettyPrinting = prettyPrinting;
      this.lenient = lenient;
      this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
      this.longSerializationPolicy = longSerializationPolicy;
      this.datePattern = datePattern;
      this.dateStyle = dateStyle;
      this.timeStyle = timeStyle;
      this.builderFactories = builderFactories;
      this.builderHierarchyFactories = builderHierarchyFactories;
    
      List factories = new ArrayList();
    
      // built-in type adapters that cannot be overridden
      factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
      factories.add(ObjectTypeAdapter.FACTORY);
    
      // the excluder must precede all adapters that handle user-defined types
      //
      factories.add(excluder);
    
      // users' type adapters
      factories.addAll(factoriesToBeAdded);
    
      // type adapters for basic platform types
      factories.add(TypeAdapters.STRING_FACTORY);
      factories.add(TypeAdapters.INTEGER_FACTORY);
      factories.add(TypeAdapters.BOOLEAN_FACTORY);
      factories.add(TypeAdapters.BYTE_FACTORY);
      factories.add(TypeAdapters.SHORT_FACTORY);
      TypeAdapter longAdapter = longAdapter(longSerializationPolicy);
      factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));
      factories.add(TypeAdapters.newFactory(double.class, Double.class,
              doubleAdapter(serializeSpecialFloatingPointValues)));
      factories.add(TypeAdapters.newFactory(float.class, Float.class,
              floatAdapter(serializeSpecialFloatingPointValues)));
      factories.add(TypeAdapters.NUMBER_FACTORY);
      factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);
      factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);
      factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));
      factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));
      factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY);
      factories.add(TypeAdapters.CHARACTER_FACTORY);
      factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
      factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
      factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
      factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
      factories.add(TypeAdapters.URL_FACTORY);
      factories.add(TypeAdapters.URI_FACTORY);
      factories.add(TypeAdapters.UUID_FACTORY);
      factories.add(TypeAdapters.CURRENCY_FACTORY);
      factories.add(TypeAdapters.LOCALE_FACTORY);
      factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
      factories.add(TypeAdapters.BIT_SET_FACTORY);
      factories.add(DateTypeAdapter.FACTORY);
      factories.add(TypeAdapters.CALENDAR_FACTORY);
      factories.add(TimeTypeAdapter.FACTORY);
      factories.add(SqlDateTypeAdapter.FACTORY);
      factories.add(TypeAdapters.TIMESTAMP_FACTORY);
      factories.add(ArrayTypeAdapter.FACTORY);
      factories.add(TypeAdapters.CLASS_FACTORY);
    
      // type adapters for composite and user-defined types
      factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
      factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
      this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
      factories.add(jsonAdapterFactory);
      factories.add(TypeAdapters.ENUM_FACTORY);
      factories.add(new ReflectiveTypeAdapterFactory(
          constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));
    
      this.factories = Collections.unmodifiableList(factories);
    }
    

    可以看到factories的添加顺序,JsonElement和Object类型的会先尝试create(),然后是exclude被排除在外的,然后是用户添加的,再然后是默认的数据类型,最后是复合类型(集合、Map、JsonAdapter注解、枚举、反射)。

    需要注意的一点是,当用户调用GsonBuilder().registerTypeAdapter()或者GsonBuilder().registerTypeHierarchyAdapter()时,最后create方法:

    public Gson create() {
      List factories = new ArrayList(this.factories.size() + this.hierarchyFactories.size() + 3);
      factories.addAll(this.factories);
      Collections.reverse(factories);
    
      List hierarchyFactories = new ArrayList(this.hierarchyFactories);
      Collections.reverse(hierarchyFactories);
      factories.addAll(hierarchyFactories);
    
      addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, factories);
    
      return new Gson(excluder, fieldNamingPolicy, instanceCreators,
          serializeNulls, complexMapKeySerialization,
          generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient,
          serializeSpecialFloatingPointValues, longSerializationPolicy,
          datePattern, dateStyle, timeStyle,
          this.factories, this.hierarchyFactories, factories);
    }
    

    可以看到,factories和hierarchyFactories都是reverse倒序的,所以你手动添加的adapter中后添加的会先调用,而且registerTypeHierarchyAdapter添加的比registerTypeAdapter添加的要晚调用。

    public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
      $Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer
          || typeAdapter instanceof JsonDeserializer
          || typeAdapter instanceof InstanceCreator
          || typeAdapter instanceof TypeAdapter);
      if (typeAdapter instanceof InstanceCreator) {
        instanceCreators.put(type, (InstanceCreator) typeAdapter);
      }
      if (typeAdapter instanceof JsonSerializer || typeAdapter instanceof JsonDeserializer) {
        TypeToken typeToken = TypeToken.get(type);
        factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter));
      }
      if (typeAdapter instanceof TypeAdapter) {
        factories.add(TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter)typeAdapter));
      }
      return this;
    }
    
    public GsonBuilder registerTypeHierarchyAdapter(Class baseType, Object typeAdapter) {
      $Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer
          || typeAdapter instanceof JsonDeserializer
          || typeAdapter instanceof TypeAdapter);
      if (typeAdapter instanceof JsonDeserializer || typeAdapter instanceof JsonSerializer) {
        hierarchyFactories.add(TreeTypeAdapter.newTypeHierarchyFactory(baseType, typeAdapter));
      }
      if (typeAdapter instanceof TypeAdapter) {
        factories.add(TypeAdapters.newTypeHierarchyFactory(baseType, (TypeAdapter)typeAdapter));
      }
      return this;
    }
    

    通过代码得知,除了调用顺序,registerTypeAdapter要多一个InstanceCreator类型的Adapter设置。

    以registerTypeAdapter为例,自定义一个:

    private class IntegerDefaultAdapter : JsonSerializer, JsonDeserializer {
        @Throws(JsonParseException::class)
        override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Int? {
            try {
                //定义为int类型,如果后台返回""或者null,则返回0
                if ("" == json.asString || "null" == json.asString) {
                    return 0
                }
            } catch (ignore: Exception) {
            }
    
            try {
                return json.asInt
            } catch (e: NumberFormatException) {
                throw JsonSyntaxException(e)
            }
    
        }
    
        override fun serialize(src: Int?, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
            return JsonPrimitive(src!!)
        }
    }
    
    factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter))
    
    public static TypeAdapterFactory newFactoryWithMatchRawType(
        TypeToken exactType, Object typeAdapter) {
      // only bother matching raw types if exact type is a raw type
      boolean matchRawType = exactType.getType() == exactType.getRawType();
      return new SingleTypeFactory(typeAdapter, exactType, matchRawType, null);
    }
    
    SingleTypeFactory(Object typeAdapter, TypeToken exactType, boolean matchRawType,
        Class hierarchyType) {
      serializer = typeAdapter instanceof JsonSerializer
          ? (JsonSerializer) typeAdapter
          : null;
      deserializer = typeAdapter instanceof JsonDeserializer
          ? (JsonDeserializer) typeAdapter
          : null;
      $Gson$Preconditions.checkArgument(serializer != null || deserializer != null);
      this.exactType = exactType;
      this.matchRawType = matchRawType;
      this.hierarchyType = hierarchyType;
    }
    

    当调用create时:

    @Override
    public  TypeAdapter create(Gson gson, TypeToken type) {
      boolean matches = exactType != null
          ? exactType.equals(type) || matchRawType && exactType.getType() == type.getRawType()
          : hierarchyType.isAssignableFrom(type.getRawType());
      return matches
          ? new TreeTypeAdapter((JsonSerializer) serializer,
              (JsonDeserializer) deserializer, gson, type, this)
          : null;
    }
    

    adapter.write和adapter.read就是:

    @Override public T read(JsonReader in) throws IOException {
      if (deserializer == null) {
        return delegate().read(in);
      }
      JsonElement value = Streams.parse(in);
      if (value.isJsonNull()) {
        return null;
      }
      return deserializer.deserialize(value, typeToken.getType(), context);
    }
    
    @Override public void write(JsonWriter out, T value) throws IOException {
      if (serializer == null) {
        delegate().write(out, value);
        return;
      }
      if (value == null) {
        out.nullValue();
        return;
      }
      JsonElement tree = serializer.serialize(value, typeToken.getType(), context);
      Streams.write(tree, out);
    }
    

    这就调用到了自定义的serialize中,最后是TypeAdapters.JSON_ELEMENT:

    public static final TypeAdapter JSON_ELEMENT = new TypeAdapter() {
      @Override public JsonElement read(JsonReader in) throws IOException {
        switch (in.peek()) {
        case STRING:
          return new JsonPrimitive(in.nextString());
        case NUMBER:
          String number = in.nextString();
          return new JsonPrimitive(new LazilyParsedNumber(number));
        case BOOLEAN:
          return new JsonPrimitive(in.nextBoolean());
        case NULL:
          in.nextNull();
          return JsonNull.INSTANCE;
        case BEGIN_ARRAY:
          JsonArray array = new JsonArray();
          in.beginArray();
          while (in.hasNext()) {
            array.add(read(in));
          }
          in.endArray();
          return array;
        case BEGIN_OBJECT:
          JsonObject object = new JsonObject();
          in.beginObject();
          while (in.hasNext()) {
            object.add(in.nextName(), read(in));
          }
          in.endObject();
          return object;
        case END_DOCUMENT:
        case NAME:
        case END_OBJECT:
        case END_ARRAY:
        default:
          throw new IllegalArgumentException();
        }
      }
    
      @Override public void write(JsonWriter out, JsonElement value) throws IOException {
        if (value == null || value.isJsonNull()) {
          out.nullValue();
        } else if (value.isJsonPrimitive()) {
          JsonPrimitive primitive = value.getAsJsonPrimitive();
          if (primitive.isNumber()) {
            out.value(primitive.getAsNumber());
          } else if (primitive.isBoolean()) {
            out.value(primitive.getAsBoolean());
          } else {
            out.value(primitive.getAsString());
          }
    
        } else if (value.isJsonArray()) {
          out.beginArray();
          for (JsonElement e : value.getAsJsonArray()) {
            write(out, e);
          }
          out.endArray();
    
        } else if (value.isJsonObject()) {
          out.beginObject();
          for (Map.Entry e : value.getAsJsonObject().entrySet()) {
            out.name(e.getKey());
            write(out, e.getValue());
          }
          out.endObject();
    
        } else {
          throw new IllegalArgumentException("Couldn't write " + value.getClass());
        }
      }
    };
    

    至此,GsonConverter的应用过程就结束了。

    你可能感兴趣的:(GsonConverterFactory源码分析)