久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Gson用戶指南

 小丑g22xft6chp 2016-06-21

作者:Inderjeet Singh, Joel Leitch, Jesse Wilson


1、Overview(概覽)


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


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


2,、Goals for Gson(Gson的目標(biāo))


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

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

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

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

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


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


以下是我們?cè)谝粋€(gè)臺(tái)式機(jī)(皓龍雙核,,8GB內(nèi)存,,64位Ubuntu系統(tǒng))下進(jìn)行大量測(cè)試得出的指標(biāo)。你可以使用PerformanceTest 類(lèi)進(jìn)行重新測(cè)試,。

    * String字符串:反序列化一個(gè)超過(guò)25MB的字符串沒(méi)有任何問(wèn)題(參考PerformanceTest類(lèi)中的disabled_testStringDeserializationPerformance方法),。

    * 大型集合對(duì)象:

        ** 序列化一個(gè)包含一百四十萬(wàn)個(gè)對(duì)象的集合(參考PerformanceTest中的disabled_testLargeCollectionSerialization方法)

        ** 反序列化一個(gè)包含八萬(wàn)七千個(gè)對(duì)象的集合(參考PerformanceTest中的disabled_testLargeCollectionDeserialization方法)

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


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


4,、Gson Users(Gson用戶)


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


5,、Using Gson(Gson的使用)


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


Gson實(shí)例并不會(huì)保存Json操作的狀態(tài)。因此,,你可以重用同一個(gè)Gson對(duì)象進(jìn)行多次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(對(duì)象示例)


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"}

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


(反序列化)

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

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


    * 完美支持對(duì)象的私有成員變量。

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

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

    * 對(duì)于null值的正確處理:

        ** 進(jìn)行序列化的時(shí)候,一個(gè)值為null的成員在輸出中將被忽略,。

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

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

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


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


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


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

public class A {
  public String a;

  class B {

    public String b;

    public B() {
      // No args constructor for B
    }
  }
}

注意:上面的類(lèi)B默認(rèn)情況下不能使用Gson序列化,。


Gson沒(méi)辦法將{"b":"abc"}反序列化為B類(lèi)的實(shí)例,因?yàn)锽是一個(gè)內(nèi)部類(lèi),。如果使用static class B將B類(lèi)標(biāo)識(shí)為靜態(tài)內(nèi)部類(lèi),,那么Gson就能夠?qū)⑦@個(gè)字符串反序列化為B類(lèi)的實(shí)例。另一種解決方法是為B類(lèi)寫(xiě)一個(gè)自定義的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();
  }
}

上面的方法可以解決這個(gè)問(wèn)題,,但是不推薦,。


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ù)雜類(lèi)型的多維數(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集合一樣

相當(dāng)可怕的:注意我們是如何定義集合的類(lèi)型的,,很不幸單純?cè)贘ava中沒(méi)有辦法解決這個(gè)問(wèn)題,。


5.5.1 Collections Limitations(集合的局限性)


    * 能夠序列化任意對(duì)象類(lèi)型的集合,但是沒(méi)辦法反序列化,,因?yàn)闆](méi)有辦法讓我們指定結(jié)果對(duì)象的類(lèi)型,。

    * 反序列化的時(shí)候,集合必須是一個(gè)具體的泛型,。


然而只要遵循良好的Java編程習(xí)慣,,所有的這些都是意義的,很少會(huì)成為一個(gè)問(wèn)題,。


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


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

class Foo<T> {
  T value;
}
Gson gson = new Gson();
Foo<Bar> foo = new Foo<Bar>();
gson.toJson(foo); // 沒(méi)辦法正確序列化foo.value

gson.fromJson(json, foo.getClass()); // 將foo.value反序列化為Bar對(duì)象失敗

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


為了解決這個(gè)問(wèn)題,,你可以為你的泛型指定一個(gè)當(dāng)前的參數(shù)類(lèi)型。你可以使用TypeToken類(lèi)來(lái)實(shí)現(xiàn):

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

gson.fromJson(json, fooType);

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

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


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

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

其中相對(duì)的集合如下:

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

里面對(duì)應(yīng)的Event類(lèi)如下:

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

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

然而,,使用fromJson(json, Collection.class)進(jìn)行反序列化將會(huì)失敗,,因?yàn)镚son沒(méi)辦法知道如何映射其中的類(lèi)型。Gson要求你在fromJson中提供一個(gè)集合的泛型版本,。因此,,你有三種選擇:

第一種選擇:使用Gson的解析API(底層的數(shù)據(jù)流解析器或者DOM解析器JsonParser)來(lái)解析出數(shù)組元素,然后為每一個(gè)數(shù)組元素調(diào)用Gson.fromJson()方法,。這是一種比較好的實(shí)現(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);
  }
}

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


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


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


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

下面是這些類(lèi)的列表:

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

  2,、java.net.URI匹配類(lèi)似“/p/google-gson/”的字符串。

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

你同樣也能在這里找到類(lèi)似JodaTime這樣常用類(lèi)的源代碼,。


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


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

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

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

  * Json反序列化解析器:需要為一個(gè)類(lèi)型定義自定義的反序列化過(guò)程。

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


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將會(huì)檢查類(lèi)型適配器是否實(shí)現(xiàn)了多個(gè)接口,如果有會(huì)全部注冊(cè)上去,。


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


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

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

Gson在序列化時(shí)進(jìn)入DateTime對(duì)象將會(huì)調(diào)用toJson()方法,。


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


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

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

當(dāng)Gson需要將一段JSON字符串片段解析為DataTime對(duì)象的時(shí)候?qū)?huì)調(diào)用fromJson()方法。


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


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

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

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

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


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

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


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


反序列化一個(gè)對(duì)象的時(shí)候,,Gson需要為對(duì)應(yīng)的類(lèi)創(chuàng)建一個(gè)默認(rèn)的實(shí)例,。

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

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


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

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


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

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

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


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


有時(shí)候你要實(shí)例化的類(lèi)型是一個(gè)帶參數(shù)的類(lèi)型,。通常這不是一個(gè)問(wèn)題,,因?yàn)閷?shí)際實(shí)例是原始類(lèi)型中的一種。

以下是一個(gè)例子:

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();
  }
}

然而,,有時(shí)候你需要?jiǎng)?chuàng)建對(duì)應(yīng)實(shí)際帶參數(shù)類(lèi)型的實(shí)例,。這種情況下,你可以使用傳遞進(jìn)createInstance方法的類(lèi)型參數(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);
  }
}

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


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


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


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


下面的例子展示了如何使用默認(rèn)的JsonPrintFormatter取代JsonCompactFormatter配置一個(gè)Gson實(shí)例,。

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(空對(duì)象支持)


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


以下是配置一個(gè)Gson實(shí)例來(lái)輸出null的方法:

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

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


下面是示例:

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注解來(lái)維護(hù)同一個(gè)對(duì)象的多個(gè)版本,。這個(gè)注解可以用于類(lèi)、字段,、未來(lái)發(fā)布、方法,。為了充分利用這個(gè)特性,,你必須配置你的Gson實(shí)例忽略掉版本比一些版本號(hào)更大的字段或者對(duì)象。如果Gson實(shí)例沒(méi)有設(shè)置版本,,那么它將序列化和反序列所有的字段和類(lèi)而不考慮版本的影響,。


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提供了多種途徑來(lái)排除頂級(jí)類(lèi)、字段和字段類(lèi)型,。以下是排除字段和類(lèi)的一些方法,。如果以下方法對(duì)于你需求來(lái)說(shuō)不安全,那么你也可以直接自定義序列化構(gòu)造器和反序列化解析器來(lái)實(shí)現(xiàn),。


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


默認(rèn)情況下,,如果你將一個(gè)字段聲明為transient,這個(gè)字段就會(huì)被排除,。同樣,,如果一個(gè)字段被標(biāo)識(shí)為“static”,那么默認(rèn)也會(huì)被排除,。如果你想把一些transient字段也包含進(jìn)來(lái),,那么你可以嘗試以下做法:

import java.lang.reflect.Modifier;

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

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

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

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


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

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

這個(gè)Gson實(shí)例將會(huì)排除類(lèi)中沒(méi)有使用@Expose注解的字段,。


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


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


下面的例子展示了如何排除由指定“@Foo”注解標(biāo)識(shí)和頂層類(lèi)型(或者聲明字段類(lèi)型)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ù)定義的字段命名策略來(lái)將標(biāo)準(zhǔn)的Java字段名(例如小寫(xiě)字母開(kāi)頭的駱駝命名法——“sampleFieldNameInJava”)覆蓋為Json的字段名(例如sample_field_name_in_java或者SampleFieldNameInJava),。參考FieldNamingPolicy類(lèi)查看預(yù)定義的命名策略,。


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


下面例子展示了如何同時(shí)使用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"}


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


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


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

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

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

  3,、使用Java ThreadLocal。

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


5.17 Streaming (流操作)


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


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


參考Gson design document中關(guān)于我們?cè)谠O(shè)計(jì)Gson過(guò)程中遇到的問(wèn)題,。里面也包含Gson和其它用于Json轉(zhuǎn)換的Java類(lèi)庫(kù)的比較,。


7、Future Enhancements to Gson(Gson未來(lái)的強(qiáng)化)


對(duì)于最新的功能增強(qiáng)建議列表或者你有什么新的建議,,可以參考Issue Session,。



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



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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多