Gson:从包装器 class 反序列化抽象子列表 class
Gson: deserialize list of abstract subclass from wrapper class
我对 Gson 和 JSON 都很陌生。
我的问题是当创建通用列表 class 并将其存储在包装对象中时,我无法反序列化回子对象。
这是主要代码
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
这是我的其余代码:
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;
}
}
我看到一些 post 谈论使用自定义 typeAdaptor 或 typeAdaptorFactory,我不确定如何使用。顺便说一句,我正在使用 Gson2.2.2 版本
这是迄今为止我找到的最佳答案...
如果有人找到更好的解决方案,请告诉我。
我还没有测试过它有多快运行。
基本上为您的主要对象创建自定义反序列化器,并在查看每个对象时确定 属性 class。
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;
}
}
}
我对 Gson 和 JSON 都很陌生。 我的问题是当创建通用列表 class 并将其存储在包装对象中时,我无法反序列化回子对象。
这是主要代码
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
这是我的其余代码:
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;
}
}
我看到一些 post 谈论使用自定义 typeAdaptor 或 typeAdaptorFactory,我不确定如何使用。顺便说一句,我正在使用 Gson2.2.2 版本
这是迄今为止我找到的最佳答案... 如果有人找到更好的解决方案,请告诉我。 我还没有测试过它有多快运行。
基本上为您的主要对象创建自定义反序列化器,并在查看每个对象时确定 属性 class。
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;
}
}
}