乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Gson用戶指南

       小丑g22xft6chp 2016-06-21

      作者:Inderjeet Singh, Joel Leitch, Jesse Wilson


      1、Overview(概覽)


      Gson是一個Java類庫,用于將Java對象轉(zhuǎn)換為它們所代表的JSON數(shù)據(jù),也可以用于將一個JSON字符串轉(zhuǎn)換為對應(yīng)的Java對象。Gson是一個開源項目,托管于http://code.google.com/p/google-gson


      Gson可以用于任意的Java對象,包括已經(jīng)存在但你沒有對應(yīng)源代碼的對象。


      2、Goals for Gson(Gson的目標)


          * 提供像toString()和構(gòu)造方法(工廠方法)一樣簡單使用的機制來將Java對象轉(zhuǎn)換為JSON或者反過來將JSON轉(zhuǎn)換為Java對象。

          * 允許將已經(jīng)存在并且不可修改的對象轉(zhuǎn)換JSON,或者反過來。

          * 允許為對象自定義映射關(guān)系。

          * 支持任意復(fù)雜的對象。

          * 生成緊湊又易讀的JSON輸出。


      3、Gson Performance and Scalability(Gson的性能和可擴展性)


      以下是我們在一個臺式機(皓龍雙核,8GB內(nèi)存,64位Ubuntu系統(tǒng))下進行大量測試得出的指標。你可以使用PerformanceTest 類進行重新測試。

          * String字符串:反序列化一個超過25MB的字符串沒有任何問題(參考PerformanceTest類中的disabled_testStringDeserializationPerformance方法)。

          * 大型集合對象:

              ** 序列化一個包含一百四十萬個對象的集合(參考PerformanceTest中的disabled_testLargeCollectionSerialization方法)

              ** 反序列化一個包含八萬七千個對象的集合(參考PerformanceTest中的disabled_testLargeCollectionDeserialization方法)

          * Gson 1.4將字節(jié)數(shù)組和集合的限制從80KB提升到11MB。


      注意:刪除disabled_前綴后再運行測試。我們添加這個前綴是為了防止每一次運行JUnit測試都要將這些測試重新運行一遍。


      4、Gson Users(Gson用戶)


      Gson原本是為Google內(nèi)部大量項目創(chuàng)建使用的,但是現(xiàn)在已經(jīng)有大量公司和公共項目都在實現(xiàn),詳細可查看這里。


      5、Using Gson(Gson的使用)


      Gson主要的類即為Gson類,你可以簡單的使用new Gson()創(chuàng)建一個Gson對象。另外也可以使用GsonBuilder這個類,它允許使用參數(shù)(例如版本控制等等)來才創(chuàng)建一個Gson實例。


      Gson實例并不會保存Json操作的狀態(tài)。因此,你可以重用同一個Gson對象進行多次Json序列化和反序列化操作。


      5.1 Primitives Examples(基本示例)


      (序列化)

      Gson gson = new Gson();
      gson.toJson(1);            ==> 結(jié)果為 1
      gson.toJson("abcd");       ==> 結(jié)果為 "abcd"
      gson.toJson(new Long(10)); ==> 結(jié)果為 10
      int[] values = { 1 };
      gson.toJson(values);       ==> 結(jié)果為 [1]

      (反序列化)

      int one = gson.fromJson("1", int.class);
      Integer one = gson.fromJson("1", Integer.class);
      Long one = gson.fromJson("1", Long.class);
      Boolean false = gson.fromJson("false", Boolean.class);
      String str = gson.fromJson("\"abc\"", String.class);
      String anotherStr = gson.fromJson("[\"abc\"]", String.class);

      5.2 Object Examples(對象示例)


      class BagOfPrimitives {
        private int value1 = 1;
        private String value2 = "abc";
        private transient int value3 = 3;
        BagOfPrimitives() {
          // no-args constructor
        }
      }

      (序列化)

      BagOfPrimitives obj = new BagOfPrimitives();
      Gson gson = new Gson();
      String json = gson.toJson(obj);
      ==>結(jié)果為{"value1":1,"value2":"abc"}

      注意,你不能序列化一個內(nèi)部包含循環(huán)引用(比如包含自身引用)的對象,那會導(dǎo)致無限遞歸。


      (反序列化)

      BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);  
      ==> obj2對象與obj對象一樣

      5.2.1 Finer Points with Objects(關(guān)于對象的一些細節(jié))


          * 完美支持對象的私有成員變量。

          * 不需要任何注解來聲明一個成員變量是否需要進行序列化和反序列化。類中所有的成員變量(包括父類的成員)默認都要進行序列化和反序列化。

          * 如果一個成員變量使用了transient關(guān)鍵字標識,默認情況下它將被忽略,將不會進行JSON的序列化和反序列化。

          * 對于null值的正確處理:

              ** 進行序列化的時候,一個值為null的成員在輸出中將被忽略。

              ** 進行反序列化的時候,對應(yīng)JSON數(shù)據(jù)中丟失的成員變量將會使用null。

          * 使用synthetic關(guān)鍵字標識的成員將被忽略,不進行JSON的序列化和反序列化。

          * 對應(yīng)外部類,內(nèi)部類、匿名類和局部類中的成員將被忽略,不進行序列化和反序列化。


      5.3 Nested Classes(including Inner Classes)—— 嵌套類(包括內(nèi)部類)


      Gson可以很容易的序列化靜態(tài)嵌套類。


      Gson也可以反序列化靜態(tài)嵌套類。但是,Gson沒辦法自動序列化一個純內(nèi)部類。因為即使內(nèi)部類的構(gòu)造方法不需要參數(shù),但實際上也需要一個外部類對象的引用。這個外部類對象在反序列化的時候已經(jīng)是不可訪問的了。你可以通過將內(nèi)部類標識為靜態(tài)類或者提供自定義的InstanceCreator來解決這個問題。以下是例子:

      public class A {
        public String a;
      
        class B {
      
          public String b;
      
          public B() {
            // No args constructor for B
          }
        }
      }

      注意:上面的類B默認情況下不能使用Gson序列化。


      Gson沒辦法將{"b":"abc"}反序列化為B類的實例,因為B是一個內(nèi)部類。如果使用static class B將B類標識為靜態(tài)內(nèi)部類,那么Gson就能夠?qū)⑦@個字符串反序列化為B類的實例。另一種解決方法是為B類寫一個自定義的InstanceCreator:

      public class InstanceCreatorForB implements InstanceCreator<A.B> {
        private final A a;
        public InstanceCreatorForB(A a)  {
          this.a = a;
        }
        public A.B createInstance(Type type) {
          return a.new B();
        }
      }

      上面的方法可以解決這個問題,但是不推薦。


      5.4 Array Examples(數(shù)組示例)


      Gson gson = new Gson();
      int[] ints = {1, 2, 3, 4, 5};
      String[] strings = {"abc", "def", "ghi"};

      (序列化)

      gson.toJson(ints);     ==> 結(jié)果為 [1,2,3,4,5]
      gson.toJson(strings);  ==> 結(jié)果為 ["abc", "def", "ghi"]

      (反序列化)

      int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class);
      ==> ints2數(shù)組與ints數(shù)組一樣

      我們同樣支持任意復(fù)雜類型的多維數(shù)組。


      5.5 Collections Examples(集合示例)


      Gson gson = new Gson();
      Collection<Integer> ints = Lists.immutableList(1,2,3,4,5);

      (序列化)

      String json = gson.toJson(ints); ==> json is [1,2,3,4,5]

      (反序列化)

      Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
      Collection<Integer> ints2 = gson.fromJson(json, collectionType);
      ==> ints2集合與ints集合一樣

      相當可怕的:注意我們是如何定義集合的類型的,很不幸單純在Java中沒有辦法解決這個問題。


      5.5.1 Collections Limitations(集合的局限性)


          * 能夠序列化任意對象類型的集合,但是沒辦法反序列化,因為沒有辦法讓我們指定結(jié)果對象的類型。

          * 反序列化的時候,集合必須是一個具體的泛型。


      然而只要遵循良好的Java編程習慣,所有的這些都是意義的,很少會成為一個問題。


      5.6 Serializing and Deserializing Generic Types(序列化和反序列化泛型)


      當你調(diào)用toJson(obj)方法的時候,Gson會調(diào)用obj.getClass()方法來獲取類中成員變量的信息來進行序列化。同樣的,你可以直接傳遞MyClass.class對象到formJson(json, MyClass.class)方法,這種做法非常適合對象不是泛型的情況。然而,如果對象是一個泛型,由于Java類型的擦除關(guān)系,泛型的信息將會丟失。下面的例子可以很好的說明這個問題:

      class Foo<T> {
        T value;
      }
      Gson gson = new Gson();
      Foo<Bar> foo = new Foo<Bar>();
      gson.toJson(foo); // 沒辦法正確序列化foo.value
      
      gson.fromJson(json, foo.getClass()); // 將foo.value反序列化為Bar對象失敗

      上面的代碼將結(jié)果解析為Bar對象失敗,是因為Gson調(diào)用foo.getClass()方法來獲取它的類信息,但是這個方法返回的是一個原始類,也就是Foo.class。這意味著Gson沒有辦法知道那是一個Foo<Bar>類型的對象,因此失敗。


      為了解決這個問題,你可以為你的泛型指定一個當前的參數(shù)類型。你可以使用TypeToken類來實現(xiàn):

      Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
      gson.toJson(foo, fooType);
      
      gson.fromJson(json, fooType);

      上面的fooType實際是定義了一個局部匿名內(nèi)部類,這個類里面包含了一個getType()方法可以返回完整的參數(shù)類型。

      5.7 Serializing and Deserializing Collection with Objects of Arbitrary Types(序列化和反序列化任意對象類型的集合)


      有時候你需要處理一些包含混合數(shù)據(jù)類的JSON數(shù)組,例如:

      ['hello',5,{name:'GREETINGS',source:'guest'}]

      其中相對的集合如下:

      Collection collection = new ArrayList();
      collection.add("hello");
      collection.add(5);
      collection.add(new Event("GREETINGS", "guest"));

      里面對應(yīng)的Event類如下:

      class Event {
        private String name;
        private String source;
        private Event(String name, String source) {
          this.name = name;
          this.source = source;
        }
      }

      你可以使用Gson序列化這個集合而不需要指定任何東西:toJson(collection)將會得到以上輸出。

      然而,使用fromJson(json, Collection.class)進行反序列化將會失敗,因為Gson沒辦法知道如何映射其中的類型。Gson要求你在fromJson中提供一個集合的泛型版本。因此,你有三種選擇:

      第一種選擇:使用Gson的解析API(底層的數(shù)據(jù)流解析器或者DOM解析器JsonParser)來解析出數(shù)組元素,然后為每一個數(shù)組元素調(diào)用Gson.fromJson()方法。這是一種比較好的實現(xiàn)方法,具體做法可以參考以下例子:

      /*
       * Copyright (C) 2011 Google Inc.
       *
       * Licensed under the Apache License, Version 2.0 (the "License");
       * you may not use this file except in compliance with the License.
       * You may obtain a copy of the License at
       *
       * http://www./licenses/LICENSE-2.0
       *
       * Unless required by applicable law or agreed to in writing, software
       * distributed under the License is distributed on an "AS IS" BASIS,
       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       * See the License for the specific language governing permissions and
       * limitations under the License.
       */
      package com.google.gson.extras.examples.rawcollections;
      
      import java.util.ArrayList;
      import java.util.Collection;
      
      import com.google.gson.Gson;
      import com.google.gson.JsonArray;
      import com.google.gson.JsonParser;
      
      public class RawCollectionsExample {
        static class Event {
          private String name;
          private String source;
          private Event(String name, String source) {
            this.name = name;
            this.source = source;
          }
          @Override
          public String toString() {
            return String.format("(name=%s, source=%s)", name, source);
          }
        }
      
        @SuppressWarnings({ "unchecked", "rawtypes" })
        public static void main(String[] args) {
          Gson gson = new Gson();
          Collection collection = new ArrayList();
          collection.add("hello");
          collection.add(5);
          collection.add(new Event("GREETINGS", "guest"));
          String json = gson.toJson(collection);
          System.out.println("Using Gson.toJson() on a raw collection: " + json);
          JsonParser parser = new JsonParser();
          JsonArray array = parser.parse(json).getAsJsonArray();
          String message = gson.fromJson(array.get(0), String.class);
          int number = gson.fromJson(array.get(1), int.class);
          Event event = gson.fromJson(array.get(2), Event.class);
          System.out.printf("Using Gson.fromJson() to get: %s, %d, %s", message, number, event);
        }
      }

      第二種選擇:注冊一個Collection.class的類型適配器來查找數(shù)組中的每一個元素,并映射為合適的對象。這種做法的缺點是它可能會破壞Gson反序列化中的其它集合類型。


      第三種選擇:注冊一個MyCollectionMemberType的類型適配器,并使用Collection<MyCollectionMemberType>的fromJson。這種做法只適合數(shù)組是頂層元素的情況,或者你可以改變字段的類型以匹配Collection<MyCollectionMemberType>。


      5.8 Built-in Serializers and Deserializers(內(nèi)置的序列化構(gòu)造器和反序列化解析器)


      Gson為常用的類提供了內(nèi)置的序列化構(gòu)造器和反序列化解析器(但是默認的設(shè)置可能不太適合你具體的要求)。

      下面是這些類的列表:

        1、java.net.URL匹配類似“http://code.google.com/p/google-gson/”的字符串。

        2、java.net.URI匹配類似“/p/google-gson/”的字符串。

        (譯注:這段話什么意思我一直理解不了= =)

      你同樣也能在這里找到類似JodaTime這樣常用類的源代碼。


      5.9 Custom Serialization and Deserialization(自定義序列化和反序列化)


      有時候默認的配置可能不符合你的要求。這種情況在處理類庫中的類(DateTime等等)時經(jīng)常出現(xiàn)。

      Gson允許你注冊自己自定義的序列化構(gòu)造器和反序列化解析器。這需要通過定義兩個部分來完成:

        * Json序列化構(gòu)造器:需要為一個對象定義自定義的序列化過程。

        * Json反序列化解析器:需要為一個類型定義自定義的反序列化過程。

        * 實例構(gòu)造器:如果有不帶參數(shù)的構(gòu)造器可以訪問或者已經(jīng)注冊了反序列化解析器,那么可以不需要提供。


      GsonBuilder gson = new GsonBuilder();
      gson.registerTypeAdapter(MyType2.class, new MyTypeAdapter());
      gson.registerTypeAdapter(MyType.class, new MySerializer());
      gson.registerTypeAdapter(MyType.class, new MyDeserializer());
      gson.registerTypeAdapter(MyType.class, new MyInstanceCreator());

      registerTypeAdapter將會檢查類型適配器是否實現(xiàn)了多個接口,如果有會全部注冊上去。


      5.9.1 Writing a Serializer(設(shè)計一個序列化構(gòu)造器)


      下面是自定義JodaTime DateTime類序列化構(gòu)造器的例子:

      private class DateTimeSerializer implements JsonSerializer<DateTime> {
        public JsonElement serialize(DateTime src, Type typeOfSrc, JsonSerializationContext context) {
          return new JsonPrimitive(src.toString());
        }
      }

      Gson在序列化時進入DateTime對象將會調(diào)用toJson()方法。


      5.9.2 Writing a Deserializer(設(shè)計一個反序列化解析器)


      下面是自定義JodaTime DateTime類反序列化解析器的例子:

      private class DateTimeDeserializer implements JsonDeserializer<DateTime> {
        public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {
          return new DateTime(json.getAsJsonPrimitive().getAsString());
        }
      }

      當Gson需要將一段JSON字符串片段解析為DataTime對象的時候?qū){(diào)用fromJson()方法。


      5.9.3 Finer points withs Serializers and Deserializers(序列化構(gòu)造器和反序列化解析器的細節(jié))


      你經(jīng)常需要為一個原始類型的泛型注冊一個單一的處理器。

        * 例如,假設(shè)你有一個“Id”類來代表或者轉(zhuǎn)換Id(例如內(nèi)部代表和外部代表)

        * Id<T>類型對于所有的泛型都具有相同的序列化過程:輸出本質(zhì)代表的Id值。

        * 反序列過程很類似但是不完全一樣:需要調(diào)用“new Id(Class<T>, String)”來返回一個Id<T>實例。


      Gson支持注冊一個單一的處理器來處理這些事情。你也可以為一個指定的類型(例如Id<RequiersSpecialHandling>需要指定的處理過程)注冊特定的處理器。

      toJson()和fromJson()包含的泛型類型參數(shù)可以幫你為所有對應(yīng)相同原始類型的泛型寫一個單一的處理器。


      5.10 Writing an Instance Creator(設(shè)計一個實例構(gòu)造器)


      反序列化一個對象的時候,Gson需要為對應(yīng)的類創(chuàng)建一個默認的實例。

      規(guī)范的類會為序列化和反序列化提供一個不帶參數(shù)的構(gòu)造方法(無論是public或者private的構(gòu)造方法)。

      典型的情況是你需要處理類庫中沒有定義不帶參數(shù)構(gòu)造方法的類,你就需要一個實例構(gòu)造器。


      5.10.1 Instance Creator Example(實例構(gòu)造器示例)

      private class MoneyInstanceCreator implements InstanceCreator<Money> {
        public Money createInstance(Type type) {
          return new Money("1000000", CurrencyCode.USD);
        }
      }


      Type可以是一個相關(guān)的泛型類型:

        * 當需要特定泛型類型信息的時候,調(diào)用構(gòu)造器是非常有用的做法。

        * 例如,Id類保存了將要被創(chuàng)建Id的類信息。


      5.10.2 InstanceCreator for a Parameterized Type(帶參數(shù)類型的實例構(gòu)造器)


      有時候你要實例化的類型是一個帶參數(shù)的類型。通常這不是一個問題,因為實際實例是原始類型中的一種。

      以下是一個例子:

      class MyList<T> extends ArrayList<T> {
      }
      
      class MyListInstanceCreator implements InstanceCreator<MyList<?>> {
          @SuppressWarnings("unchecked")
        public MyList<?> createInstance(Type type) {
          // No need to use a parameterized list since the actual instance will have the raw type anyway.
          return new MyList();
        }
      }

      然而,有時候你需要創(chuàng)建對應(yīng)實際帶參數(shù)類型的實例。這種情況下,你可以使用傳遞進createInstance方法的類型參數(shù)。以下是例子:

      public class Id<T> {
        private final Class<T> classOfId;
        private final long value;
        public Id(Class<T> classOfId, long value) {
          this.classOfId = classOfId;
          this.value = value;
        }
      }
      
      class IdInstanceCreator implements InstanceCreator<Id<?>> {
        public Id<?> createInstance(Type type) {
          Type[] typeParameters = ((ParameterizedType)type).getActualTypeArguments();
          Type idType = typeParameters[0]; // Id has only one parameterized type T
          return Id.get((Class)idType, 0L);
        }
      }

      上面的例子中,由于沒有實際傳遞進來的帶參數(shù)類型,Id類的實例沒辦法創(chuàng)建。我們通過傳遞type參數(shù)到方法里面來解決這個問題。上面例子中的type對象是一個java帶參數(shù)類型,假如是Id<Foo>,那么創(chuàng)建的實例應(yīng)該是Id<Foo>實例。因為Id類只包含一個帶參數(shù)類型的參數(shù)T,我們直接使用getActualTypeArgument()方法返回的數(shù)組中的第一個元素,在這個例子中也就是Foo.class。


      5.11 Compact Vs. Pretty Printing for JSON Output Fromat(對比Gson緊湊型和優(yōu)雅型的輸出格式)


      Gson提供的默認輸出格式是緊湊型的JSON格式。這意味著在輸出的JSON結(jié)構(gòu)中沒有任何空白,也就是在輸出的JSON中字段名和字段值、對象成員、數(shù)組中的對象之間沒有任何留白。另外,“null”字段將會在輸出中被忽略(注意null值仍然包含在對象的集合或者數(shù)組中)。參考下面Null Object Support章節(jié)來配置Gson輸出所有的null值。


      如果你想要使用優(yōu)雅的格式輸出,你可以使用GsonBuilder配置你的Gson實例。由于我們的public API中沒有開放JsonFormatter,因此沒有辦法配置默認JSON輸出的設(shè)置和邊距。目前,我們只提供了一個默認的JsonPrintFormatter,它規(guī)定輸出的格式每一行的長度為80個字符,2個字符縮進,4個字符的右邊距。


      下面的例子展示了如何使用默認的JsonPrintFormatter取代JsonCompactFormatter配置一個Gson實例。

      Gson gson = new GsonBuilder().setPrettyPrinting().create();
      String jsonOutput = gson.toJson(someObject);Gson gson = new GsonBuilder().setPrettyPrinting().create();
      String jsonOutput = gson.toJson(someObject);


      5.12 Null Object Support(空對象支持)


      Gson對于null字段的默認處理是忽略掉,因為這樣才能生成更加緊湊的輸出格式。然而,客戶端必須為這些字段定義默認值,這樣JSON格式才能轉(zhuǎn)換回對應(yīng)的Java對象。


      以下是配置一個Gson實例來輸出null的方法:

      Gson gson = new GsonBuilder().serializeNulls().create();

      注意:當使用Gson序列化null值的時候,它將添加一個JsonNull元素到JsonElement結(jié)構(gòu)中。因此,這個對象能夠被用于自定義的序列化和反序列化。


      下面是示例:

      public class Foo {
        private final String s;
        private final int i;
      
        public Foo() {
          this(null, 5);
        }
      
        public Foo(String s, int i) {
          this.s = s;
          this.i = i;
        }
      }
      
      Gson gson = new GsonBuilder().serializeNulls().create();
      Foo foo = new Foo();
      String json = gson.toJson(foo);
      System.out.println(json);
      
      json = gson.toJson(null);
      System.out.println(json);
      


      ======== 輸出結(jié)果 ========
      {"s":null,"i":5}
      null

      5.13 Versioning Support(版本支持)


      可以使用@Since注解來維護同一個對象的多個版本。這個注解可以用于類、字段、未來發(fā)布、方法。為了充分利用這個特性,你必須配置你的Gson實例忽略掉版本比一些版本號更大的字段或者對象。如果Gson實例沒有設(shè)置版本,那么它將序列化和反序列所有的字段和類而不考慮版本的影響。


      public class VersionedClass {
        @Since(1.1) private final String newerField;
        @Since(1.0) private final String newField;
        private final String field;
      
        public VersionedClass() {
          this.newerField = "newer";
          this.newField = "new";
          this.field = "old";
        }
      }
      
      VersionedClass versionedObject = new VersionedClass();
      Gson gson = new GsonBuilder().setVersion(1.0).create();
      String jsonOutput = gson.toJson(someObject);
      System.out.println(jsonOutput);
      System.out.println();
      
      gson = new Gson();
      jsonOutput = gson.toJson(someObject);
      System.out.println(jsonOutput);

      ======== 輸出結(jié)果 ========

      {"newField":"new","field":"old"}

      {"newerField":"newer","newField":"new","field":"old"}


      5.14 Excluding Fields From Serialization and Deserialization(在序列化和反序列中排除字段)


      Gson提供了多種途徑來排除頂級類、字段和字段類型。以下是排除字段和類的一些方法。如果以下方法對于你需求來說不安全,那么你也可以直接自定義序列化構(gòu)造器和反序列化解析器來實現(xiàn)。


      5.14.1 Java Modifier Exclusion(Java修正器排除)


      默認情況下,如果你將一個字段聲明為transient,這個字段就會被排除。同樣,如果一個字段被標識為“static”,那么默認也會被排除。如果你想把一些transient字段也包含進來,那么你可以嘗試以下做法:

      import java.lang.reflect.Modifier;
      
      Gson gson = new GsonBuilder()
          .excludeFieldsWithModifiers(Modifier.STATIC)
          .create();

      注意:你可以同時在excludeFieldsWithModifiers方法中包含多個Modifier數(shù)值,例如:

      Gson gson = new GsonBuilder()
          .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE)
          .create();

      5.14.2 Gson's @Expose(Gson的@Expose注解)


      這個功能提供一種途徑來表示你的對象中哪些字段是JSON的序列化和反序列化時候要排除的。要使用這個注解,你需要使用以下方式創(chuàng)建Gson實例:

      new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();

      這個Gson實例將會排除類中沒有使用@Expose注解的字段。


      5.14.3 User Defined Exclusion Strategies(用戶自定義排除策略)


      如果上述排除字段和類型的方法不符合你的要求,你可以定義自己的排除策略然后添加到Gson中。參考ExclusionStrategy的Java文檔獲取更多信息。


      下面的例子展示了如何排除由指定“@Foo”注解標識和頂層類型(或者聲明字段類型)String的字段。


        @Retention(RetentionPolicy.RUNTIME)
        @Target({ElementType.FIELD})
        public @interface Foo {
          // Field tag only annotation
        }
      
        public class SampleObjectForTest {
          @Foo private final int annotatedField;
          private final String stringField;
          private final long longField;
          private final Class<?> clazzField;
      
          public SampleObjectForTest() {
            annotatedField = 5;
            stringField = "someDefaultValue";
            longField = 1234;
          }
        }
      
        public class MyExclusionStrategy implements ExclusionStrategy {
          private final Class<?> typeToSkip;
      
          private MyExclusionStrategy(Class<?> typeToSkip) {
            this.typeToSkip = typeToSkip;
          }
      
          public boolean shouldSkipClass(Class<?> clazz) {
            return (clazz == typeToSkip);
          }
      
          public boolean shouldSkipField(FieldAttributes f) {
            return f.getAnnotation(Foo.class) != null;
          }
        }
      
        public static void main(String[] args) {
          Gson gson = new GsonBuilder()
              .setExclusionStrategies(new MyExclusionStrategy(String.class))
              .serializeNulls()
              .create();
          SampleObjectForTest src = new SampleObjectForTest();
          String json = gson.toJson(src);
          System.out.println(json);
        }

      ======== 輸出結(jié)果 ========

      {"longField":1234}


      5.15 JSON Field Naming Support(JSON字段命名支持)


      Gson支持一些預(yù)定義的字段命名策略來將標準的Java字段名(例如小寫字母開頭的駱駝命名法——“sampleFieldNameInJava”)覆蓋為Json的字段名(例如sample_field_name_in_java或者SampleFieldNameInJava)。參考FieldNamingPolicy類查看預(yù)定義的命名策略。


      Gson同樣也提供了一個基于策略的注解允許客戶端為每一個字段自定義名字。注意基于策略的注解會檢查字段的名字,如果注解值提供了一個無效的名字將會拋出“Runtime”異常。


      下面例子展示了如何同時使用Gson的預(yù)定義命名策略和注解命名策略特性:

      private class SomeObject {
        @SerializedName("custom_naming") private final String someField;
        private final String someOtherField;
      
        public SomeObject(String a, String b) {
          this.someField = a;
          this.someOtherField = b;
        }
      }
      
      SomeObject someObject = new SomeObject("first", "second");
      Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
      String jsonRepresentation = gson.toJson(someObject);
      System.out.println(jsonRepresentation);

      ======== 輸出結(jié)果 ========

      {"custom_naming":"first","SomeOtherField":"second"}


      如果你需要自定義命名策略(參考這個討論),你可以使用@SerializedName注解。


      5.16 Sharing State Across Custom Serializers and Deserializers(通過自定義序列化構(gòu)造器和反序列化解析器共享狀態(tài))


      有時候你需要通過自定義序列化構(gòu)造器和反序列化解析器來共享狀態(tài)(參考這里的討論)。你可以通過以下三種方法來達到目的:

        1、使用靜態(tài)變量保存共享的狀態(tài)。

        2、聲明序列化構(gòu)造器或反序列化解析器作為父類的內(nèi)部類,然后使用父類的實例變量保存共享的狀態(tài)。

        3、使用Java ThreadLocal。

      1和2是非線程安全的做法,3是線程安全的。


      5.17 Streaming (流操作)


      由于Gson的對象模型和數(shù)據(jù)綁定,你可以使用Gson讀寫一個數(shù)據(jù)流。你可以組合數(shù)據(jù)流和對象模型入口來獲取最佳的實現(xiàn)。


      6、Issues in Designing Gson(設(shè)計中的問題)


      參考Gson design document中關(guān)于我們在設(shè)計Gson過程中遇到的問題。里面也包含Gson和其它用于Json轉(zhuǎn)換的Java類庫的比較。


      7、Future Enhancements to Gson(Gson未來的強化)


      對于最新的功能增強建議列表或者你有什么新的建議,可以參考Issue Session。



      原文地址:https://sites.google.com/site/gson/gson-user-guide



        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多