美文网首页
GsonConverterFactory源码分析

GsonConverterFactory源码分析

作者: 就叫汉堡吧 | 来源:发表于2020-11-14 09:08 被阅读0次
    • 前言

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

    • GsonRequestBodyConverter

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

      static final class Body<T> extends ParameterHandler<T> {
        private final Method method;
        private final int p;
        private final Converter<T, RequestBody> converter;
      
        Body(Method method, int p, Converter<T, RequestBody> 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<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

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

      Response<T> 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<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();
          }
        }
      }
      
    • 源码分析

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

      @Override
      public Converter<ResponseBody, ?> responseBodyConverter(
          Type type, Annotation[] annotations, Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new GsonResponseBodyConverter<>(gson, adapter);
      }
      
      @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);
      }
      

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

      public static TypeToken<?> get(Type type) {
        return new TypeToken<Object>(type);
      }
      

      看一下gson的getAdapter做了什么:

      public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
        TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
        if (cached != null) {
          return (TypeAdapter<T>) cached;
        }
      
        Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
        boolean requiresThreadLocalCleanup = false;
        if (threadCalls == null) {
          threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
          calls.set(threadCalls);
          requiresThreadLocalCleanup = true;
        }
      
        // the key and value type parameters always agree
        FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
        if (ongoingCall != null) {
          return ongoingCall;
        }
      
        try {
          FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
          threadCalls.put(type, call);
      
          for (TypeAdapterFactory factory : factories) {
            TypeAdapter<T> 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<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
          boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
          boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
          LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
          int timeStyle, List<TypeAdapterFactory> builderFactories,
          List<TypeAdapterFactory> builderHierarchyFactories,
          List<TypeAdapterFactory> 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<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
      
        // 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<Number> 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<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>(this.factories.size() + this.hierarchyFactories.size() + 3);
        factories.addAll(this.factories);
        Collections.reverse(factories);
      
        List<TypeAdapterFactory> hierarchyFactories = new ArrayList<TypeAdapterFactory>(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<Int>, JsonDeserializer<Int> {
          @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 <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        boolean matches = exactType != null
            ? exactType.equals(type) || matchRawType && exactType.getType() == type.getRawType()
            : hierarchyType.isAssignableFrom(type.getRawType());
        return matches
            ? new TreeTypeAdapter<T>((JsonSerializer<T>) serializer,
                (JsonDeserializer<T>) 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<JsonElement> JSON_ELEMENT = new TypeAdapter<JsonElement>() {
        @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<String, JsonElement> 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源码分析

          本文链接:https://www.haomeiwen.com/subject/jovbbktx.html