2015-02-06 60 views
1

我對Gson和JSON都很新。 我的問題是當創建一個泛型類的列表並將其存儲在包裝obj中時,我無法反序列化回到子obj。Gson:從封裝類中反序列化抽象子類的列表

這裏是主代碼

public static void main(String[] arg) { 
    block b = new block(); 

    List<Shape> shapes = new ArrayList<Shape>(); 

    Circle c = new Circle(); 
    c.setRadius(1); 
    c.setType("cir"); 
    Square s = new Square(); 
    s.setSide(4); 
    s.setType("sq"); 

    shapes.add(c); 
    shapes.add(s); 

    b.setShape(shapes); 

    String json = new Gson().toJson(b); 
    System.out.println(json); 

    Object obj = new Gson().fromJson(json, block.class); 
    block bobj = (block) obj; 

    List<Shape> li = bobj.getShape(); 
    Shape sh = (Shape)li.get(0); 

    System.out.println(sh.getClass().getCanonicalName()); 
    System.out.println(sh.toString()); 
} 

我得到這個作爲輸出

{"shape":[{"radius":1,"type":"cir"},{"side":4,"type":"sq"}]} 
    com.ups.pcs.test.TestTypeAdaptor.Shape 
    [email protected]

這裏是我的代碼的其餘部分:

static class block implements Serializable { 
     List<Shape> shape = null; 

    public block() { 

    } 

    public List<Shape> getShape() { 
     return shape; 
    } 

    public void setShape(List<Shape> shape) { 
     this.shape = shape; 
    } 

    } 

    static class Shape implements Serializable{ 
    String type; 

    public Shape(){} 
    public void setType(String type) { 
     this.type = type; 
    } 

    public String getType() { 
     return type; 
    } 

    } 

    private static final class Circle extends Shape implements Serializable{ 
    int radius; 

    public Circle(){} 
    public int getRadius() { 
     return radius; 
    } 

    public void setRadius(int radius) { 
     this.radius = radius; 
    } 

    public String toString() { 
     return "t: " + type + "r: " + radius; 
    } 
    } 

    private static final class Square extends Shape implements Serializable{ 
    int side; 

    public Square(){} 
    public int getSide() { 
     return side; 
    } 

    public void setSide(int side) { 
     this.side = side; 
    } 

    public String toString() { 
     return "t: " + type + "s: " + side; 
    } 
    } 

我已經看到了一些帖子說起使用自定義typeAdaptor ortypeAdaptorFactory,我不知道如何使用。順便說一句我正在使用Gson2.2.2版本

+0

同時修改Shape爲抽象它無法成功運行。 '線程中的異常「main」java.lang.RuntimeException:無法調用public com.ups.pcs.test.TestTypeAdaptor $ Shape()with no args' – user3431327 2015-02-06 22:11:04

回答

2

這是我發現迄今爲止的最佳答案... 請讓我知道是否有人找到更好的解決方案,然後這個。 我還沒有測試知道它運行的速度。

基本上爲您的主對象創建自定義的反序列化器,並在查看每個對象時確定屬性類。

public static class BlockDeserializer implements JsonDeserializer<Block> { 

    @Override 
    public Block deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
     if (json == null) 
      return null; 
     else { 
      Block block = new Block(); 
      JsonObject jo = json.getAsJsonObject(); 
      JsonArray ja = jo.getAsJsonArray("shape"); 

      List<Shape> shapes = new ArrayList<Shape>(); 

      for(JsonElement je : ja) { 
       JsonObject jeo = je.getAsJsonObject(); 

       if(jeo.get("radius") != null) {    
        shapes.add(new Gson().fromJson(jeo , Circle.class));      
       } else { 
        shapes.add(new Gson().fromJson(jeo , Square.class));   
       } 
      } 

      block.shape = shapes; 

      return block; 
     } 
    } 
}