Проблема GSON и InstanceCreator

у меня есть следующие POJOs:

public interface Shape {
    public double calcArea();
    public double calcPerimeter();
}

public class Rectangle implement Shape {
    // Various properties of a rectangle
}

public class Circle implements Shape {
    // Various properties of a circle
}

public class ShapeHolder {
    private List<Shape> shapes;

    // other stuff
}

у меня нет проблем с Gson для сериализации экземпляра ShapeHolder JSON. Но когда я пытаюсь десериализовать строку этого JSON обратно в ShapeHolder например, я получаю ошибки:

String shapeHolderAsStr = getString();
ShapeHolder holder = gson.fromJson(shapeHodlderAsStr, ShapeHolder.class);

Броски:

Exception in thread "main" java.lang.RuntimeException: Unable to invoke no-args constructor for interface    
net.myapp.Shape. Register an InstanceCreator with Gson for this type may fix this problem.
    at com.google.gson.internal.ConstructorConstructor.construct(ConstructorConstructor.java:167)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:162)
    ... rest of stack trace ommitted for brevity

так я посмотрел здесь и начал реализовывать свой собственный ShapeInstanceCreator:

public class ShapeInstanceCreator implements InstanceCreator<Shape> {
    @Override
    public Shape createInstance(Type type) {
        // TODO: ???
        return null;
    }
}

но теперь я застрял: мне дали только java.lang.reflect.Type, но мне действительно нужен java.lang.Object так что я может писать код как:

public class ShapeInstanceCreator implements InstanceCreator<Shape> {
    @Override
    public Shape createInstance(Type type) {
        Object obj = convertTypeToObject(type);

        if(obj instanceof Rectangle) {
            Rectangle r = (Rectangle)obj;
            return r;
        } else {
            Circle c = (Circle)obj;
            return c;
        }

        return null;
    }
}

что я могу сделать? Заранее спасибо!

обновление:

по предложению @ raffian (ссылка, которую он/она опубликовал), я реализовал InterfaceAdapter ровно как и в ссылке (я не менял что-нибудь). Теперь я получаю следующее исключение:

Exception in thread "main" com.google.gson.JsonParseException: no 'type' member found in what was expected to be an interface wrapper
    at net.myapp.InterfaceAdapter.get(InterfaceAdapter.java:39)
    at net.myapp.InterfaceAdapter.deserialize(InterfaceAdapter.java:23)

какие идеи?

2 ответов


ты этой? Похоже на хороший чистый способ реализации InstanceCreators.

Я тоже использовал Gson, но переключился на FlexJSON из-за проблем с сериализацией. С Flex вам не нужны создатели экземпляров, просто убедитесь, что ваши объекты имеют геттеры/сеттеры для всех полей на основе спецификации JavaBean, и вам хорошо идти:

 ShapeHolder sh = new ShapeHolder();
 sh.addShape(new Rectangle());
 sh.addShape(new Circle());
 JSONSerializer ser = new JSONSerializer();
 String json = ser.deepSerialize(sh);
 JSONDeserializer<ShapeHolder> der = new JSONDeserializer<ShapeHolder>();
 ShapeHolder sh2 = der.deserialize(json);

обратите внимание, что FlexJSON добавляет имя класса как часть json, как показано ниже, сериализует время.

{
    "HTTPStatus": "OK",
    "class": "com.XXX.YYY.HTTPViewResponse",
    "code": null,
    "outputContext": {
        "class": "com.XXX.YYY.ZZZ.OutputSuccessContext",
        "eligible": true
    }
}

таким образом, JSON будет cumber; но вам не нужно писать InstanceCreator что требуется в GSON.