2011-12-20 24 views
0

首先,我有一個非常簡單的java bean它可以輕鬆地序列化到JSON:如何使用google-gson將這種自定義類型序列化爲json?

class Node { 
    private String text; 
    // getter and setter 
} 

Node node = new Node(); 
node.setText("Hello"); 

String json = new Gson().toJson(node); 
// json is { text: "Hello" } 

然後,爲了使這種豆有一定的動態值,所以我創建了一個「WithData」基類:

Class WithData { 
    private Map<String, Object> map = new HashMap<String, Object>(); 
    public void setData(String key, Object value) { map.put(key, value); } 
    public Object getData(String key) = { return map.get(key); } 
} 

class Node extends WithData { 
    private String text; 
    // getter and setter 
} 

現在我可以設置更多的數據節點:

Node node = new Node(); 
node.setText("Hello"); 
node.setData("to", "The world"); 

但GSON會忽略「來」,結果仍是{ text: "Hello" }。我希望它是:{ text: "Hello", to: "The world" }

有什麼辦法編寫WithData型串行,所有的類來擴展它不僅會產生自己的屬性,以JSON,而且數據在map

我試圖實現一個自定義的序列化程序,但失敗了,因爲我不知道如何讓Gson首先序列化屬性,然後是map中的數據。

+0

您是否嘗試將您的地圖字段公開? – 2011-12-20 08:33:57

+0

這沒有幫助,我希望地圖的鍵將是json的鍵 – Freewind 2011-12-20 08:37:03

回答

5

我現在要做的是創建一個自定義序列:

public static class NodeSerializer implements JsonSerializer<Node> { 
    public JsonElement serialize(Node src, 
      Type typeOfSrc, JsonSerializationContext context) { 
     JsonObject obj = new JsonObject(); 
     obj.addProperty("id", src.id); 
     obj.addProperty("text", src.text); 
     obj.addProperty("leaf", src.leaf); 
     obj.addProperty("level", src.level); 
     obj.addProperty("parentId", src.parentId); 
     obj.addProperty("order", src.order); 
     Set<String> keys = src.getDataKeys(); 
     if (keys != null) { 
      for (String key : keys) { 
       obj.add(key, context.serialize(src.getData(key))); 
      } 
     } 
     return obj; 
    }; 
} 

然後使用GsonBuilder把它轉換:

Gson gson = new GsonBuilder(). 
    registerTypeAdapter(Node.class, new NodeSerializer()).create(); 

Tree tree = new Tree(); 
tree.addNode(node1); 
tree.addNode(node2); 

gson.toJson(tree); 

然後我預計在樹中的節點將被轉換。唯一無聊的是我需要每次創建一個特殊的Gson

4

其實,你應該期望Node:WithData連載作爲

{ 
    "text": "Hello", 
    "map": { 
    "to": "the world" 
    } 
} 

(這是與「漂亮打印」打開)

我能得到該序列,當我想你的例子。這是我確切的代碼

import com.google.gson.Gson; 
import com.google.gson.GsonBuilder; 

import java.net.MalformedURLException; 

import java.util.HashMap; 
import java.util.Map; 


public class Class1 { 

    public static void main(String[] args) throws MalformedURLException { 
    GsonBuilder gb = new GsonBuilder(); 
    Gson g = gb.setPrettyPrinting().create(); 

    Node n = new Node(); 
    n.setText("Hello"); 
    n.setData("to", "the world"); 

    System.out.println(g.toJson(n)); 
    } 
    private static class WithData { 
    private Map<String, Object> map = new HashMap<String, Object>(); 
    public void setData(String key, Object value) { map.put(key, value); } 
    public Object getData(String key) { return map.get(key); } 
    } 
    private static class Node extends WithData { 
    private String text; 
    public Node() { } 
    public String getText() {return text;} 
    public void setText(String text) {this.text = text;} 
    } 
} 

我用的是JDK器(javac)編譯 - 這是重要的,因爲其他的編譯器(那些包含在一些IDEs)可以去除哪些GSON依賴作爲其優化的一部分或信息混淆處理。

下面是我使用的編譯和執行命令:

「C:\ Program Files文件\的Java \ jdk1.6.0_24 \斌\的javac.exe」 -classpath GSON-2.0.jar Class1.java

「C:\ Program Files文件\的Java \ jdk1.6.0_24 \斌\ java.exe的」。-classpath; GSON-2.0.jar的Class1

對於這個測試的目的,我把Gson jar文件與測試類文件位於同一文件夾中。

請注意,我使用的是Gson 2.0; 1.x可能會有不同的表現。

您的JDK可能安裝在與我不同的位置,因此如果您使用這些命令,請確保根據需要調整JDK的路徑。

相關問題