从使用到源码—Gson(上)

2018-08-13  本文已影响0人  horseLai

引言

使用默认配置的Gson

    //System.out.println("");
    final String jsonStr = "{'data':'this is data', 'result':{'name':'horseLai', 'age':24}}"; 
    
    Gson gson = new Gson();
     
    //输出:{"data":"hello gson","result":{"name":"horseLai","age":20}}
    Data data = new Data();
    User user = new User();
    data.setResult(user);
    data.setData("hello gson");
    user.setAge(20);
    user.setName("horseLai");
    String json = gson.toJson(data);
    System.out.println(json);
    
    //输出:Data{data='this is data', result=User{name='horseLai', age=24}}
    Data data1 = gson.fromJson(jsonStr, Data.class);
    System.out.println(data1 );
    static class Data {
        private String data;
        private User result;
        // 省略set/get/toString
    } 
    static class User {
        private String name;
        private int age; 
        // 省略set/get/toString
    }

定制使用TypeAdapter<T>

    final String jsonStr = "{'data':'this is data', 'result':{'name':'horseLai', 'age':24}}";
    //输出:Data{data='this is data', result=User{name='horseLai', age=24}} 
    Gson gson = new GsonBuilder()
     .registerTypeAdapter(Data.class, new MyTypeAdapter())
     .enableComplexMapKeySerialization()
     .serializeNulls()
     .setDateFormat(DateFormat.LONG)
     .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
     .setPrettyPrinting()
     .setVersion(1.0)
     .create();
     
    TypeAdapter<Data> adapter = gson.getAdapter(Data.class);
    try {
        StringReader stringReader = new StringReader(jsonStr);
        Data read = adapter.read(new JsonReader(stringReader));
        System.out.println(read);
    } catch (IOException e) {
        e.printStackTrace();
    }
// 对应于我们的`Json`数据定制
static class MyTypeAdapter extends TypeAdapter<Data> {
    @Override
    public void write(JsonWriter out, Data value) throws IOException
    {
        if (value == null) {
            out.nullValue();
            return;
        } 
         out.setLenient(true);
            out.beginObject();
            out.name("data");
            out.value(value.data);

            out.name("result");
            out.beginObject();
            out.name("name");
            out.value(value.getResult().name);
            out.name("age");
            out.value(value.getResult().age);
            out.endObject();

            out.endObject();
    } 
    @Override
    public Data read(JsonReader in) throws IOException
    {
        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }
        Data data = new Data();
        User user = new User();
        in.setLenient(true);
        in.beginObject();
        while (in.hasNext()) {
            switch (in.nextName()) { // 先读取字段名称,然后逐个去匹配
                case "data":
                    data.setData(in.nextString());
                    break;
                case "result":
                    in.beginObject();
                    break;
                case "name":
                    user.setName(in.nextString());
                    break;
                case "age":
                    user.setAge(in.nextInt());
                    break;
            }
        }
        data.setResult(user);
        in.endObject();
        in.endObject();
        return data;
    }
} 
 
 public JsonWriter value(Number value) throws IOException {
    // . . . 
    String string = value.toString();
    if (!lenient && (string.equals("-Infinity") 
            || string.equals("Infinity") || string.equals("NaN"))) {
      throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
    }
    beforeValue();
    out.append(string);
    return this;
  }
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) { 
   if (TypeToken缓存中是否存在){
        return (TypeAdapter<T>) cached;
    } 
   if (ThreadLocal中是否保存有){
        return   (FutureTypeAdapter<T>) cached;
    }
    
    for (TypeAdapterFactory factory : factories) {
        TypeAdapter<T> candidate = factory.create(this, type);
        if (candidate != null) {
          call.setDelegate(candidate);   // 缓存至ThreadLocal
          typeTokenCache.put(type, candidate);  // 缓存至TokenCache
          return candidate;
        }
      } 
    // 实在没找到可以匹配的 
      throw new IllegalArgumentException("GSON cannot handle " + type);
    // . . . 
}
 @Override public T read(JsonReader in) throws IOException {
     // . . . 
      T instance = constructor.construct();
        in.beginObject();
        while (in.hasNext()) {
          String name = in.nextName();
          BoundField field = boundFields.get(name);
          if (field == null || !field.deserialized) {
            in.skipValue();
          } else {
            field.read(in, instance);
          }       
        // . . .
        in.endObject();
      return instance;
    }

JsonParser

       final String jsonStr = "{'data':'this is data', 'result':{'name':'horseLai', 'age':24}}";
        JsonParser jsonParser = new JsonParser();
        JsonObject jsonObject = jsonParser.parse(jsonStr).getAsJsonObject();
 
        String data = jsonObject.get("data").getAsString();
        JsonObject result = jsonObject.get("result").getAsJsonObject();

        Data data1 = new Data();
        data1.setData(data);
        User user = new User();
        user.setAge(result.get("age").getAsInt());
        user.setName(result.get("name").getAsString());
        data1.setResult(user);
        //输出:Data{data='this is data', result=User{name='horseLai', age=24}}
        System.out.println(data1);
 public JsonElement parse(JsonReader json) throws JsonIOException, JsonSyntaxException {
    // . . .
      return Streams.parse(json); 
  }

  // Streams#parse
 public static JsonElement parse(JsonReader reader) throws JsonParseException {
    // . . . 
      reader.peek(); 
      return TypeAdapters.JSON_ELEMENT.read(reader);  
  }

小结

Gson#toJson 
-> 建立JsonWriter.AppendableWriter 数据流
-> 创建对应于我们所需数据类型的TypeToken
-> 根据TypeToken 查找TypeToken缓存中是否已经存在已经对应的使用过的TypeAdapter
-> 根据TypeToken 查找ThreadLocal是否存在对应的使用过的TypeAdapter
-> 如果没有,则遍历所有TypeAdapterFactory并创建对应于我们所需类型的TypeAdapter,
   如果还没匹配,那么也会ReflectiveTypeAdapterFactory,只要我们指定的类型是Java实体类的话,毕竟是通过反射操作。
   Gson中实现的TypeAdapter几乎已经覆盖到了我们常用的所有类型,具体可查阅TypeAdapters类。
-> 在TypeAdapter.write中提取Java实体类字段值写入到流中,转换成json数据
上一篇下一篇

猜你喜欢

热点阅读