我正在尝试使用JTS库,并且在序列化具有Point属性的类时遇到了一个奇怪的问题。
import java.io.IOException;
import java.io.Serializable;
import com.owlike.genson.Genson;
import com.owlike.genson.TransformationException;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.PrecisionModel;
public class TestJTS implements Serializable {
/**
*
*/
private static final long serialVersionUID = 7778701490986272036L;
protected Point point = null;
public TestJTS() {
super();
}
/**
* @param args
*/
public static void main(String[] args) {
TestJTS test = new TestJTS();
GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
Coordinate coordinate = new Coordinate(10.0, 100.1);
Point point = gf.createPoint(coordinate);
test.setPoint(point);
System.out.println("Point: " + test.getPoint());
Genson genson = new Genson();
try {
String json = genson.serialize(test);
System.out.println(json);
} catch (TransformationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
}
下面的这个最小示例为我提供了例外,但我不明白为什么。我的代码错了吗?我对使用JTS库是否有错误的假设?
Point: POINT (10 100.1)
com.owlike.genson.TransformationException: Could not serialize property 'point' from class TestJTS
at com.owlike.genson.reflect.PropertyAccessor.couldNotSerialize(PropertyAccessor.java:48)
at com.owlike.genson.reflect.PropertyAccessor.serialize(PropertyAccessor.java:31)
at com.owlike.genson.reflect.BeanDescriptor.serialize(BeanDescriptor.java:87)
at com.owlike.genson.convert.NullConverter$NullConverterWrapper.serialize(NullConverter.java:51)
at com.owlike.genson.Genson.serialize(Genson.java:341)
at com.owlike.genson.Genson.serialize(Genson.java:222)
at TestJTS.main(TestJTS.java:40)
Caused by: com.owlike.genson.TransformationException: Could not serialize property 'boundary' from class com.vividsolutions.jts.geom.Point
at com.owlike.genson.reflect.PropertyAccessor.couldNotSerialize(PropertyAccessor.java:48)
at com.owlike.genson.reflect.PropertyAccessor.serialize(PropertyAccessor.java:31)
at com.owlike.genson.reflect.BeanDescriptor.serialize(BeanDescriptor.java:87)
at com.owlike.genson.convert.NullConverter$NullConverterWrapper.serialize(NullConverter.java:51)
at com.owlike.genson.convert.CircularClassReferenceConverterFactory$CircularConverter.serialize(CircularClassReferenceConverterFactory.java:30)
at com.owlike.genson.reflect.PropertyAccessor.serialize(PropertyAccessor.java:29)
... 5 more
Caused by: com.owlike.genson.TransformationRuntimeException: Could not access value of property named 'boundary' using accessor public abstract com.vividsolutions.jts.geom.Geometry com.vividsolutions.jts.geom.Geometry.getBoundary() from class com.vividsolutions.jts.geom.Geometry
at com.owlike.genson.reflect.PropertyAccessor.couldNotAccess(PropertyAccessor.java:42)
at com.owlike.genson.reflect.PropertyAccessor$MethodAccessor.access(PropertyAccessor.java:72)
at com.owlike.genson.reflect.PropertyAccessor.serialize(PropertyAccessor.java:26)
at com.owlike.genson.reflect.BeanDescriptor.serialize(BeanDescriptor.java:87)
at com.owlike.genson.convert.NullConverter$NullConverterWrapper.serialize(NullConverter.java:51)
at com.owlike.genson.convert.CircularClassReferenceConverterFactory$CircularConverter.serialize(CircularClassReferenceConverterFactory.java:30)
at com.owlike.genson.reflect.PropertyAccessor.serialize(PropertyAccessor.java:29)
... 9 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.owlike.genson.reflect.PropertyAccessor$MethodAccessor.access(PropertyAccessor.java:66)
... 14 more
Caused by: java.lang.IllegalArgumentException: This method does not support GeometryCollection arguments
at com.vividsolutions.jts.geom.Geometry.checkNotGeometryCollection(Geometry.java:1782)
at com.vividsolutions.jts.geom.GeometryCollection.getBoundary(GeometryCollection.java:154)
... 19 more
最佳答案
这里的问题是Genson试图根据其getter方法和公共字段来序列化您的点,这似乎与JTS混合得不好。最好的解决方案是编写一个将使用工厂构建的自定义转换器,这使您可以将某些东西委派给现有机制。
class JTSPointConverterFactory implements Factory<Converter<Point>> {
@Override public Converter<Point> create(Type type,
Genson genson) {
final Converter<Coordinate> coordianteConverter = genson.provideConverter(Coordinate.class);
Converter<Point> pointConverter = new Converter<Point>() {
private final GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
@Override public void serialize(Point point, ObjectWriter writer,
Context ctx) throws TransformationException, IOException {
Coordinate coordinate = point.getCoordinate();
writer.beginObject()
.writeName("x").writeValue(coordinate.x)
.writeName("y").writeValue(coordinate.y);
if (!Double.isNaN(coordinate.z))
writer.writeName("z").writeValue(coordinate.z);
writer.endObject();
}
@Override public Point deserialize(ObjectReader reader, Context ctx)
throws TransformationException, IOException {
// just delegate to gensons Coordiante converter the deserialization
return gf.createPoint(coordianteConverter.deserialize(reader, ctx));
}
};
return pointConverter;
}
}
// now register your factory
Genson genson = new Genson.Builder()
.withConverterFactory(new JTSPointConverterFactory())
.create();
genson.serialize(testJts);