2016-01-20 73 views
2

考慮下面的JSON一個JSON:參考父對象反序列化使用GSON

{ 
    "authors": [{ 
     "name": "Stephen King", 
     "books": [{ 
      "title": "Carrie" 
     }, { 
      "title": "The Shining" 
     }, { 
      "title": "Christine" 
     }, { 
      "title": "Pet Sematary" 
     }] 
    }] 
} 

這個對象結構:

public class Author { 
    private List<Book> books; 
    private String name; 
} 

public class Book { 
    private transient Author author; 
    private String title; 
} 

有沒有一種方法,使用谷歌的Java庫GSON,反序列化JSON並且書籍對象具有對「父」作者對象的引用?

是否有可能使用自定義解串器的而不使用

  • 如果是:如何?
  • 如果否:是否仍然可以使用自定義解串器來做到這一點?
+1

'有沒有可能不使用自定義解串器? 「我不認爲這是可能的,因爲性質如何反序列化。 '是否仍然可以用定製的解串器來做到這一點?'是的,有可能這樣做。只需查找有關該部分的教程,stackoverflow就此主題提供了幾個問題和答案。 –

+0

@Tezla你能指點我一篇文章或一個解釋我如何實現這一點的stackoverflow,因爲我沒有找到任何東西。這就是爲什麼我決定發佈我的問題。它會幫助我很多。 – Thermech

回答

4

在這種情況下,我將實現父對象的自定義JsonDeserializer,並傳播Author信息,像這樣:

public class AuthorDeserializer implements JsonDeserializer<Author> { 
    @Override 
    public Author deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
     final JsonObject authorObject = json.getAsJsonObject(); 

     Author author = new Author(); 
     author.name = authorObject.get("name").getAsString(); 

     Type booksListType = new TypeToken<List<Book>>(){}.getType(); 
     author.books = context.deserialize(authorObject.get("books"), booksListType); 

     for(Book book : author.books) { 
      book.author = author; 
     } 

     return author; 
    } 
} 

請注意,我的例子中省略了錯誤檢查。你會使用它,像這樣:

Gson gson = new GsonBuilder() 
    .registerTypeAdapter(Author.class, new AuthorDeserializer()) 
    .create(); 

要顯示它的工作,我脫下只是「作者」從你的例子關鍵JSON,讓我做到這一點:

JsonElement authorsJson = new JsonParser().parse(json).getAsJsonObject().get("authors"); 

Type authorList = new TypeToken<List<Author>>(){}.getType(); 
List<Author> authors = gson.fromJson(authorsJson, authorList); 
for(Author a : authors) { 
    System.out.println(a.name); 
    for(Book b : a.books) { 
     System.out.println("\t " + b.title + " by " + b.author.name); 
    } 
} 

打印了:

Stephen King 
    Carrie by Stephen King 
    The Shining by Stephen King 
    Christine by Stephen King 
    Pet Sematary by Stephen King 
+0

很簡單!我怎麼沒有想到它。非常感謝 – Thermech

+0

但是,如果作者對象有多個字段,我不想手動映射它們。而且我也不想在每次更改Author對象時更改解串器。你有什麼建議? – Thermech

+2

@Thermech - 我不確定GSON有沒有辦法解決這個問題。您的其他選項是執行默認的反序列化,然後對結果進行後處理。你可以爲Author創建一個構造函數,它需要一個'JsonObject'並用它來填充原始字段,並將該邏輯保存在'Author'類中。同樣,您可以創建一個構造函數,它將所有基元類型作爲參數,這將迫使您在對類進行更改時更新解串器。 – nickb