4

我正在尝试使用Gson解析GeoJSON,并且我有一个看起来像这样的 JSON(简化):

{"type": "FeatureCollection",
 "features": [
{ "type": "Feature", "name": "Afghanistan", "geometry": 
    { "type": "Polygon", "coordinates": 
        <<a 3-dimensional double array (double[][][] in Java)>>
    } 
},
{ "type": "Feature", "name": "Indonesia", "geometry":
    { "type": "MultiPolygon", "coordinates":
        <<a 4-dimensional double array (double[][][][] in Java)>>
    }
},
//etc...
 ]
}

我需要有一个可以与 Gson 对象相关联的 java 类才能使用它,但我正在努力处理变量coordinates不相同的类似对象数组。我有相当于:

class FeatureCollection{
    String type;
    Feature[] features;
}
class Feature{
    String type,name;
    Shape geometry;
}
class Shape{
    String type;
    ??? coordinates;
}
  • 当我尝试使用double[][][]而不是???,我得到一个com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a double but was BEGIN_ARRAY at line 6 column 146
  • 当我尝试创建Shape一个抽象类并使用 and 的子类时MultiPolygonPolygon尝试Gson实例化 a Shapeand 错误。

我可以使用泛型或其他鬼鬼祟祟的东西来解决这个问题吗?

4

1 回答 1

3

您需要拥有自己的自定义JsonDeserializer,因为该coordinates变量没有一组已定义的数组维度。我建议为形状使用一个接口,然后为它编写一个反序列化器,如下所示:

public interface Shape {

    ShapeType getType();

    enum ShapeType { Polygon, MultiPolygon }
}

然后是每种类型的实现。ShapeType.Polygon

public class PolygonShape implements Shape {

    private final ShapeType type = ShapeType.Polygon;
    private double[][][] coordinates;

    public ShapeType getType() {
        return type;
    }

    public double[][][] getCoordinates() {
        return coordinates;
    }

    public void setCoordinates(double[][][] coordinates) {
        this.coordinates = coordinates;
    }
}

并且ShapeType.MultiPolygon

public class MultiPolygonShape implements Shape {

    private final ShapeType type = ShapeType.MultiPolygon;
    private double[][][][] coordinates;

    public ShapeType getType() {
        return type;
    }

    public double[][][][] getCoordinates() {
        return coordinates;
    }

    public void setCoordinates(double[][][][] coordinates) {
        this.coordinates = coordinates;
    }
}

最后,您的反序列化器将依赖于type每个实现:

public class ShapeDeserializer implements JsonDeserializer<Shape> {

    @Override
    public Shape deserialize(JsonElement json, Type typeOfT,
            JsonDeserializationContext context) throws JsonParseException {
        JsonObject jsonObject = json.getAsJsonObject();
        ShapeType type = context.deserialize(jsonObject.get("type"), ShapeType.class);
        switch (type) {
            case Polygon:
                return context.deserialize(json, PolygonShape.class);
            case MultiPolygon:
                return context.deserialize(json, MultiPolygonShape.class);
            default:
                throw new JsonParseException("Unrecognized shape type: " + type);
        }
    }
}

使用它,您还可以根据形状类型创建其他实现并将它们添加switch到支持它们。例如,要支持一种新Line类型:

case Line:
    return context.deserialize(json, LineShape.class);

不要忘记使用以下GsonBuilder.registerTypeAdapter方法注册它:

GsonBuilder builder;
// ...
builder.registerTypeAdapter(Shape.class, new ShapeDeserializer());
于 2013-08-31T19:08:36.507 回答