java - Gson:从包装类反序列化抽象子类列表

标签 java json serialization gson deserialization

我对 Gson 和 JSON 都很陌生。 我的问题是,当创建泛型类列表并将其存储在包装器 obj 中时,我无法反序列化回子 obj。

主要代码如下

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
     com.ups.pcs.test.TestTypeAdaptor$Shape@3c6f579

here are my rest of the code:

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 或 typeAdaptorFactory 的帖子,我不知道如何使用。顺便说一句,我正在使用 Gson2.2.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;
        }
    }
}   

关于java - Gson:从包装类反序列化抽象子类列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28374793/

相关文章:

javascript - 如何在 HTML 页面上提取 JSON 数据

c# - 无法将 JSON 数组反序列化为类型 - Json.NET

java - Android NoSuchElementException 和扫描仪

java - Newbee Drools 链表过滤

java - ant:编译尽可能多的类以防出现编译错误

json - 如何在Go中直接打印从http.Get获取的json到http.ResponseWriter?

ios - Swift 核心数据关系和播种数据

Hadoop自带的Serialization和AVRO序列化的关系?

javascript - 在 .Net 中是否有更优雅的手工制作序列化 Javascript 的方法?

java - 大小为 2N 的数组中的 N 个重复元素