Gson的使用

目錄

Gson(又稱Google Gson)是Google公司發(fā)布的一個開放源代碼的Java庫手蝎,主要用途為序列化Java對象為JSON字符串掀鹅,或反序列化JSON字符串成Java對象。而JSON(JavaScript Object Notation) 是一種輕量級的數(shù)據(jù)交換格式,易于人閱讀和編寫丙者,同時也易于機器解析和生成,廣泛應(yīng)用于各種數(shù)據(jù)的交互中营密,尤其是服務(wù)器與客戶端的交互械媒。

一. Gson處理對象的幾個重要點

  1. 推薦把成員變量都聲明稱private的

  2. 沒有必要用注解(@Expose 注解)指明某個字段是否會被序列化或者反序列化,所有包含在當(dāng)前類(包括父類)中的字段都應(yīng)該默認(rèn)被序列化或者反序列化

  3. 如果某個字段被 transient 這個Java關(guān)鍵詞修飾,就不會被序列化或者反序列化

  4. 下面的實現(xiàn)方式能夠正確的處理null

    當(dāng)序列化的時候纷捞,如果對象的某個字段為null痢虹,是不會輸出到Json字符串中的。

    當(dāng)反序列化的時候主儡,某個字段在Json字符串中找不到對應(yīng)的值奖唯,就會被賦值為null

  5. 如果一個字段是 synthetic的,他會被忽視,也即是不應(yīng)該被序列化或者反序列化

  6. 內(nèi)部類(或者anonymous class(匿名類)缀辩,或者local class(局部類臭埋,可以理解為在方法內(nèi)部聲明的類))的某個字段和外部類的某個字段一樣的話,就會被忽視臀玄,不會被序列化或者反序列化

二. Gson中的一些注解

@SerializedName注解

該注解能指定該字段在JSON中對應(yīng)的字段名稱

public class Box {

  @SerializedName("w")
  private int width;
    
  @SerializedName("h")
  private int height;

  @SerializedName("d")
  private int depth;

  // Methods removed for brevity
}

也就是說{"w":10,"h":20,"d":30} 這個JSON 字符串能夠被解析到上面的width瓢阴,height和depth字段中。

@Expose注解

該注解能夠指定該字段是否能夠序列化或者反序列化健无,默認(rèn)的是都支持(true)荣恐。

public class Account {

  @Expose(deserialize = false)
  private String accountNumber;

  @Expose
  private String iban;

  @Expose(serialize = false)
  private String owner;

  @Expose(serialize = false, deserialize = false)
  private String address;

  private String pin;
}

需要注意的通過 builder.excludeFieldsWithoutExposeAnnotation()方法是該注解生效。

final GsonBuilder builder = new GsonBuilder();
builder.excludeFieldsWithoutExposeAnnotation();
final Gson gson = builder.create();

@Since和@Until注解

Since代表“自從”累贤,Until 代表”一直到”叠穆。它們都是針對該字段生效的版本。比如說 @Since(1.2)代表從版本1.2之后才生效臼膏,@Until(0.9)代表著在0.9版本之前都是生效的硼被。

public class SoccerPlayer {

  private String name;

  @Since(1.2)
  private int shirtNumber;

  @Until(0.9)
  private String country;

  private String teamName;

  // Methods removed for brevity
}

也就是說我們利用方法builder.setVersion(1.0)定義版本1.0,如下:

 final GsonBuilder builder = new GsonBuilder();
    builder.setVersion(1.0);

    final Gson gson = builder.create();

    final SoccerPlayer account = new SoccerPlayer();
    account.setName("Albert Attard");
    account.setShirtNumber(10); // Since version 1.2
    account.setTeamName("Zejtun Corinthians");
    account.setCountry("Malta"); // Until version 0.9

    final String json = gson.toJson(account);
    System.out.printf("Serialised (version 1.0)%n  %s%n", json);

由于shirtNumbercountry作用版本分別是1.2之后渗磅,和0.9之前嚷硫,所以在這里都不會得到序列化,所以輸出結(jié)果是:

Serialised (version 1.0)
  {"name":"Albert Attard","teamName":"Zejtun Corinthians"}

三. Gson 序列化

序列化基本類型

Gson gson = new Gson();
gson.toJson(1);            ==> prints 1
gson.toJson("abcd");       ==> prints "abcd"
gson.toJson(new Long(10)); ==> prints 10
int[] values = { 1 };
gson.toJson(values);       ==> prints [1]

序列化對象

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

將上邊的pojo序列化

BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);  
==> json is {"value1":1,"value2":"abc"}

transient 關(guān)鍵字防止序列化.

序列化集合

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]

序列化集合很容易,但反序列化不易. 看之后的反序列化就知道了.

Gson解析器進行序列化

英文Serialize和format都對應(yīng)序列化始鱼,這是一個Java對象到JSON字符串的過程仔掸。
接著看一個例子,下面分別是java類和以及我們期望的JSON數(shù)據(jù):

public class Book {
  private String[] authors;
  private String isbn10;
  private String isbn13;
  private String title;
  //為了代碼簡潔,這里移除getter和setter方法等

}
{
  "title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases",
  "isbn-10": "032133678X",
  "isbn-13": "978-0321336781",
  "authors": [
    "Joshua Bloch",
    "Neal Gafter"
  ]
}

你肯定能發(fā)現(xiàn)JSON數(shù)據(jù)中出現(xiàn)了isbn-10isbn-13, 我們怎么把字段數(shù)據(jù)isbn10isbn13轉(zhuǎn)化為JSON數(shù)據(jù)需要的isbn-10isbn-13,Gson當(dāng)然為我們提供了對應(yīng)的解決方案

采用上面提到的@SerializedName注解医清。

public class Book {
  private String[] authors;

  @SerializedName("isbn-10")
  private String isbn10;

  @SerializedName("isbn-13")
  private String isbn13;
  private String title;
  //為了代碼簡潔起暮,這里移除getter和setter方法等

}
public class BookSerialiser implements JsonSerializer {

    @Override
    public JsonElement serialize(final Book book, final Type typeOfSrc, final JsonSerializationContext context) {
       
        final JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("title", book.getTitle());
        jsonObject.addProperty("isbn-10", book.getIsbn10());
        jsonObject.addProperty("isbn-13", book.getIsbn13());

        final JsonArray jsonAuthorsArray = new JsonArray();
        for (final String author : book.getAuthors()) {
            final JsonPrimitive jsonAuthor = new JsonPrimitive(author);
            jsonAuthorsArray.add(jsonAuthor);
        }
        jsonObject.add("authors", jsonAuthorsArray);

        return jsonObject;
    }
}

下面對序列化過程進行大致的分析:

  • JsonSerializer是一個接口,我們需要提供自己的實現(xiàn)会烙,來滿足自己的序列化要求负懦。
public interface JsonSerializer<T> {

  /**
   * Gson 會在解析指定類型T數(shù)據(jù)的時候觸發(fā)當(dāng)前回調(diào)方法進行序列化
   *
   * @param T 需要轉(zhuǎn)化為Json數(shù)據(jù)的類型,對應(yīng)上面的Book
   * @return 返回T指定的類對應(yīng)JsonElement
   */
  public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context);
}
  • 首先在上面的代碼中柏腻,我們需要創(chuàng)建的是一個JsonElement對象密似,這里對應(yīng)Book是一個Json串,所以創(chuàng)建一個JsonObject類型葫盼。
    final JsonObject jsonObject = new JsonObject();
  • 然后我們將相應(yīng)字段里面的數(shù)據(jù)填充到j(luò)sonObject里面残腌。
jsonObject.addProperty...
jsonObject.add...

下面是jsonObject中的添加方法:

img

因為JsonElement是JsonObject和JsonArray、JsonPrimitive..的抽象父類,所以最后返回的還是一個JsonElement 類型抛猫,這里對應(yīng)的是jsonObject蟆盹。完成了javaBean->JSON數(shù)據(jù)的轉(zhuǎn)化。

同樣需要配置

// Configure GSON
    final GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Book.class, new BookSerialiser());
    gsonBuilder.setPrettyPrinting();
    final Gson gson = gsonBuilder.create();

    final Book javaPuzzlers = new Book();
    javaPuzzlers.setTitle("Java Puzzlers: Traps, Pitfalls, and Corner Cases");
    javaPuzzlers.setIsbn10("032133678X");
    javaPuzzlers.setIsbn13("978-0321336781");
    javaPuzzlers.setAuthors(new String[] { "Joshua Bloch", "Neal Gafter" });

    // Format to JSON
    final String json = gson.toJson(javaPuzzlers);
    System.out.println(json);

這里對應(yīng)的是gsonBuilder.registerTypeAdapter(Book.class, new BookSerialiser())方法進行JsonSerializer的配置闺金。在上面例子中逾滥,通過調(diào)用gsonBuilder.setPrettyPrinting();`方法還告訴了 Gson 對生成的 JSON 對象進行格式化。

四. Gson 反序列化

反序列化基本類型

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

反序列化對象

class BagOfPrimitives {
  private int value1 = 1;
  private String value2 = "abc";
  private transient int value3 = 3;
  BagOfPrimitives() {
    // no-args constructor
  }
}
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);   
==> obj2 is just like obj

這樣就可以反序列化了.

反序列化集合

Gson gson = new Gson();
Collection<Integer> ints = Lists.immutableList(1,2,3,4,5);
Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);
ints2 is same as ints

這里使用TypeToken<T>去接收類型,因為它在反序列化的時候并不知道反序列化的是什么類型,所以通過

new TypeToken<傳入集合或其他的類型>(){}.getType();

來取得類型,然后再在

 gson.fromJson(json, collectionType);

取得反序列化的數(shù)據(jù).

可以序列化任意對象的集合但不能反序列化.這是因為沒有途徑使得用戶可以去提示該對象的類型败匹。

反序列化過程中寨昙,集合必須制定特定的泛型

所有這些是有意義的,它使得你在遵循好的Java編碼實踐的過程中很少發(fā)生錯誤掀亩。

Gson解析器進行反序列化

英文parse和deserialise對應(yīng)反序列化舔哪,這是一個字符串轉(zhuǎn)換成Java對象的過程。
我們同樣采用上面一小節(jié)的代碼片段槽棍,只不過現(xiàn)在我們需要做的是將:

{
  "title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases",
  "isbn-10": "032133678X",
  "isbn-13": "978-0321336781",
  "authors": [
    "Joshua Bloch",
    "Neal Gafter"
  ]
}

轉(zhuǎn)化為對應(yīng)的Book實體類

利用@SerializedName 注解
也就是說我們的實體類Book.java可以這么寫:

public class Book {
  private String[] authors;

  @SerializedName("isbn-10")
  private String isbn10;

  @SerializedName(value = "isbn-13", alternate = {"isbn13","isbn.13"})
  private String isbn13;
  private String title;
  //為了代碼簡潔捉蚤,這里移除getter和setter方法等

}
img

可以看到這里我們在@SerializedName 注解使用了一個value, alternate字段,value也就是默認(rèn)的字段,對序列化和反序列化都有效炼七,alternate只有反序列化才有效果缆巧。也就是說一般服務(wù)器返回給我們JSON數(shù)據(jù)的時候可能同樣的一個圖片,表示"image","img","icon"等豌拙,我們利用@SerializedName 中的alternate字段就能解決這個問題陕悬,全部轉(zhuǎn)化為我們實體類中的圖片字段。

我們在序列化的時候使用的是JsonSerialize ,這里對應(yīng)使用JsonDeserializer

我們將解析到的json數(shù)據(jù)傳遞給Book的setter方法即可按傅。

public class BookDeserializer implements JsonDeserializer<Book> {

  @Override
  public Book deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
      throws JsonParseException {
    final JsonObject jsonObject = json.getAsJsonObject();

    final JsonElement jsonTitle = jsonObject.get("title");
    final String title = jsonTitle.getAsString();

    final String isbn10 = jsonObject.get("isbn-10").getAsString();
    final String isbn13 = jsonObject.get("isbn-13").getAsString();

    final JsonArray jsonAuthorsArray = jsonObject.get("authors").getAsJsonArray();
    final String[] authors = new String[jsonAuthorsArray.size()];
    for (int i = 0; i < authors.length; i++) {
      final JsonElement jsonAuthor = jsonAuthorsArray.get(i);
      authors[i] = jsonAuthor.getAsString();
    }

    final Book book = new Book();
    book.setTitle(title);
    book.setIsbn10(isbn10);
    book.setIsbn13(isbn13);
    book.setAuthors(authors);
    return book;
  }
}

和Gson序列化章節(jié)一樣捉超,我們這里接著分析我們是怎么將JSON數(shù)據(jù)解析(反序列化)為實體類的:

  • 因為我們可以發(fā)現(xiàn)上面的JSON數(shù)據(jù)是一個{}大括號包圍的,也就意味著這是一個Json對象逞敷。所以首先我們通過final JsonObject jsonObject = json.getAsJsonObject();`將我們的JsonElement轉(zhuǎn)化為JsonObject
  • 通過jsonObject.get("xxx").getAsString()的形式獲取相應(yīng)String的值
  • 通過jsonObject.get("xx").getAsJsonArray();獲取相應(yīng)的json數(shù)組,并遍歷出其中的相應(yīng)字段值
  • 通過setter方法灌侣,將獲取到的值設(shè)置給Book類推捐。
  • 最終返回的是 Book的對象實例。完成了JSON->javaBean的轉(zhuǎn)化
  • 同樣需要配置
  • 關(guān)于從本地流中讀取Json數(shù)據(jù)可以使用 InputStreamReader完成
// Configure Gson
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Book.class, new BookDeserializer());
Gson gson = gsonBuilder.create();

// The JSON data
try(Reader reader = new         InputStreamReader(Main.class.getResourceAsStream("/part1/sample.json"), "UTF-8")){

      // Parse JSON to Java
      Book book = gson.fromJson(reader, Book.class);
      System.out.println(book);
}

五. TypeAdapter的使用

TypeAdapter介紹

除了運用JsonSerializer和JsonDeserializer進行JSON和java實體類之間的相互轉(zhuǎn)化侧啼。我們還可以利用TypeAdapter更加高效的完成這個需求牛柒。

之前在上一篇文中提到的JsonSerializerJsonDeserializer解析的時候都利用到了一個中間件-JsonElement,比如下方的序列化過程痊乾∑け冢可以看到我們在把Java對象轉(zhuǎn)化為JSON字符串的時候都會用到這個中間件JsonElement

img

TypeAdapter的使用正是去掉了這個中間層,直接用流來解析數(shù)據(jù)哪审,極大程度上提高了解析效率蛾魄。

New applications should prefer TypeAdapter, whose streaming API is more efficient than this interface’s tree API.

應(yīng)用中應(yīng)當(dāng)盡量使用TypeAdapter,它流式的API相比于之前的樹形解析API將會更加高效。

TypeAdapter作為一個抽象類提供兩個抽象方法滴须。分別是write()read()方法,也對應(yīng)著序列化和反序列化舌狗。如下圖所示:

img

下面就讓我們來一起使用和了解TypeAdapter吧。

TypeAdapter實例

Book.java實體類:

package com.javacreed.examples.gson.part1;

public class Book {

  private String[] authors;
  private String isbn;
  private String title;

//為了代碼簡潔扔水,這里移除getter和setter方法等
}

直接貼代碼痛侍,具體序列化和反序列化的TypeAdapter類,這里是BookTypeAdapter.java

public class BookTypeAdapter extends TypeAdapter {

  @Override
  public Book read(final JsonReader in) throws IOException {
    final Book book = new Book();

    in.beginObject();
    while (in.hasNext()) {
      switch (in.nextName()) {
      case "isbn":
        book.setIsbn(in.nextString());
        break;
      case "title":
        book.setTitle(in.nextString());
        break;
      case "authors":
        book.setAuthors(in.nextString().split(";"));
        break;
      }
    }
    in.endObject();

    return book;
  }

  @Override
  public void write(final JsonWriter out, final Book book) throws IOException {
    out.beginObject();
    out.name("isbn").value(book.getIsbn());
    out.name("title").value(book.getTitle());
    out.name("authors").value(StringUtils.join(book.getAuthors(), ";"));
    out.endObject();
  }
}

同樣這里設(shè)置TypeAdapter之后還是需要配置(注冊),可以注意到的是gsonBuilder.registerTypeAdapter(xxx)方法進行注冊在我們之前的JsonSerializerJsonDeserializer中也有使用:

final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Book.class, new BookTypeAdapter());
final Gson gson = gsonBuilder.create();

下面對兩個write方法和read方法進行分別的闡述:

TypeAdapter中的write方法

write()方法中會傳入JsonWriter魔市,和需要被序列化的Book對象的實例主届,采用和PrintStream類似的方式 寫入到JsonWriter中。

@Override
  public void write(final JsonWriter out, final Book book) throws IOException {
    out.beginObject();
    out.name("isbn").value(book.getIsbn());
    out.name("title").value(book.getTitle());
    out.name("authors").value(StringUtils.join(book.getAuthors(), ";"));
    out.endObject();
  }

下面是上面代碼的步驟:

  • out.beginObject()產(chǎn)生{,如果我們希望產(chǎn)生的是一個數(shù)組對象待德,對應(yīng)的使用beginArray()
  • out.name("isbn").value(book.getIsbn()); out.name("title").value(book.getTitle());分別獲取book中的isbn和title字段并且設(shè)置給Json對象中的isbn和title君丁。也就是說上面這段代碼,會在json對象中產(chǎn)生:
"isbn": "978-0321336781",
"title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases",
  • out.name("authors").value(StringUtils.join(book.getAuthors(), ";"));則會對應(yīng)著:
 "authors": "Joshua Bloch;Neal Gafter"
  • 同理 out.endObject()則對應(yīng)著}
  • 那么整個上面的代碼也就會產(chǎn)生JSON對象:
{
  "isbn": "978-0321336781",
  "title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases",
  "authors": "Joshua Bloch;Neal Gafter"
}

這里需要注意的是磅网,如果沒有調(diào)用 out.endObject()產(chǎn)生},那么你的項目會報出 JsonSyntaxException錯誤

Exception in thread "main" com.google.gson.JsonSyntaxException: java.io.EOFException: End of input at line 4 column 40
    at com.google.gson.Gson.fromJson(Gson.java:813)
    at com.google.gson.Gson.fromJson(Gson.java:768)
    at com.google.gson.Gson.fromJson(Gson.java:717)
    at com.google.gson.Gson.fromJson(Gson.java:689)
    at com.javacreed.examples.gson.part1.Main.main(Main.java:41)
Caused by: java.io.EOFException: End of input at line 4 column 40
    at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1377)
    at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:471)
    at com.google.gson.stream.JsonReader.hasNext(JsonReader.java:403)
    at com.javacreed.examples.gson.part1.BookTypeAdapter.read(BookTypeAdapter.java:33)
    at com.javacreed.examples.gson.part1.BookTypeAdapter.read(BookTypeAdapter.java:1)
    at com.google.gson.Gson.fromJson(Gson.java:803)
    ... 4 more

TypeAdapter中的read方法

read()方法將會傳入一個JsonReader對象實例并返回反序列化的對象谈截。

 @Override
  public Book read(final JsonReader in) throws IOException {
    final Book book = new Book();

    in.beginObject();
    while (in.hasNext()) {
      switch (in.nextName()) {
      case "isbn":
        book.setIsbn(in.nextString());
        break;
      case "title":
        book.setTitle(in.nextString());
        break;
      case "authors":
        book.setAuthors(in.nextString().split(";"));
        break;
      }
    }
    in.endObject();

    return book;
  }

下面是這段代碼的步驟:

  • 同樣是通過in.beginObject();in.endObject();對應(yīng)解析{,}
  • 通過
while (in.hasNext()) {
      switch (in.nextName()) {
      }
}

來完成每個JsonElement的遍歷,并且通過switch...case的方法獲取Json對象中的鍵值對。并通過我們Book實體類Setter方法進行設(shè)置涧偷。

while (in.hasNext()) {
   switch (in.nextName()) {
      case "isbn":
        book.setIsbn(in.nextString());
        break;
      case "title":
        book.setTitle(in.nextString());
        break;
      case "authors":
        book.setAuthors(in.nextString().split(";"));
        break;
   }
}

同樣需要注意的是,如果沒有執(zhí)行in.endObject()簸喂,將會出現(xiàn)JsonIOException的錯誤:

Exception in thread "main" com.google.gson.JsonIOException: JSON document was not fully consumed.
    at com.google.gson.Gson.assertFullConsumption(Gson.java:776)
    at com.google.gson.Gson.fromJson(Gson.java:769)
    at com.google.gson.Gson.fromJson(Gson.java:717)
    at com.google.gson.Gson.fromJson(Gson.java:689)
    at com.javacreed.examples.gson.part1.Main.main(Main.java:41)

下面給出使用TypeAdapter的完整代碼:

 public static void main(final String[] args) throws IOException {
    final GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Book.class, new BookTypeAdapter());
    gsonBuilder.setPrettyPrinting();

    final Gson gson = gsonBuilder.create();

    final Book book = new Book();
    book.setAuthors(new String[] { "Joshua Bloch", "Neal Gafter" });
    book.setTitle("Java Puzzlers: Traps, Pitfalls, and Corner Cases");
    book.setIsbn("978-0321336781");

    final String json = gson.toJson(book);
    System.out.println("Serialised");
    System.out.println(json);

    final Book parsedBook = gson.fromJson(json, Book.class);
    System.out.println("\nDeserialised");
    System.out.println(parsedBook);
  }

對應(yīng)的編譯結(jié)果為:

Serialised
{
  "isbn": "978-0321336781",
  "title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases",
  "authors": "Joshua Bloch;Neal Gafter"
}

Deserialised
Java Puzzlers: Traps, Pitfalls, and Corner Cases [978-0321336781]
Written by:
  >> Joshua Bloch
  >> Neal Gafter
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市燎潮,隨后出現(xiàn)的幾起案子喻鳄,更是在濱河造成了極大的恐慌,老刑警劉巖确封,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件除呵,死亡現(xiàn)場離奇詭異,居然都是意外死亡爪喘,警方通過查閱死者的電腦和手機颜曾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秉剑,“玉大人泛豪,你說我怎么就攤上這事≌炫簦” “怎么了诡曙?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長略水。 經(jīng)常有香客問我价卤,道長,這世上最難降的妖魔是什么渊涝? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任慎璧,我火速辦了婚禮床嫌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘炸卑。我一直安慰自己既鞠,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布盖文。 她就那樣靜靜地躺著嘱蛋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪五续。 梳的紋絲不亂的頭發(fā)上洒敏,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機與錄音疙驾,去河邊找鬼凶伙。 笑死,一個胖子當(dāng)著我的面吹牛它碎,可吹牛的內(nèi)容都是我干的函荣。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼扳肛,長吁一口氣:“原來是場噩夢啊……” “哼傻挂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起挖息,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤金拒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后套腹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绪抛,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年电禀,在試婚紗的時候發(fā)現(xiàn)自己被綠了幢码。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡尖飞,死狀恐怖症副,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情葫松,我是刑警寧澤瓦糕,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布底洗,位于F島的核電站腋么,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏亥揖。R本人自食惡果不足惜珊擂,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一圣勒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧摧扇,春花似錦圣贸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至在张,卻和暖如春用含,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背帮匾。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工啄骇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瘟斜。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓缸夹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親螺句。 傳聞我的和親對象是個殘疾皇子虽惭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android中Gson的使用 1 簡介 Gson是一個Java庫,作用是將Java對象轉(zhuǎn)換成它對應(yīng)的JSON表示...
    LuckyXiang閱讀 19,865評論 2 3
  • 【前言】最近項目中對數(shù)據(jù)的解析都使用了Gson壹蔓,艸蛋的是每次都要手寫JavaBean對象很麻煩趟妥。抱著能否簡化的心態(tài)...
    erki_stwee閱讀 1,041評論 0 0
  • 關(guān)于json,gson是最常用到的一個庫佣蓉。平常使用時我通常使用Gson gson = new Gson();的方式...
    黑泥卡閱讀 10,068評論 1 14
  • 翻譯自JavaCreed首先看一個Json字符串 如果我們不使用Gson注解@SerializeName披摄,那怎么來...
    董成鵬閱讀 3,087評論 0 1
  • 項目中一直使用的原生解析JSONObject.參考鏈接http://www.reibang.com/p/e740...
    全球頂尖偽極客閱讀 5,026評論 0 0