如何解析GSON的接口

时间:2017-10-22 15:50:17

标签: java json jackson gson

我有一个带嵌套接口的接口模型。 对于每个接口,主要还有一个具体的实现类,如:

public interface Book {

    String getTitle();
}

public class BookImpl implements Book {

    private String title;

    @Override
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

现在解析json,如:

gson.fromJson(json, Book.class);

不起作用,因为它不知道实现类。

所以我创建了一个自定义反序列化器,如:

public class BookDeserializer implements JsonDeserializer<Book> {

    @Override
    public Book deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
        return context.deserialize(json, BookImpl.class);
    }
}

但我为模型中的每个界面执行此操作。

这是正确的方法吗?创建这样一个简单的解串器?我觉得应该有一个更简单的方法。

与杰克逊一样,我会创建一个自定义杰克逊Module并注册类型映射,如:

.addAbstractTypeMapping(Book.class, BookImpl.class)

GSON也可以吗?

1 个答案:

答案 0 :(得分:1)

您可以使用JsonDeserializer

的通用版本
public static class MyDeserializer implements JsonDeserializer {
    private Class<?> implClass;

    public BookDeserializer(Class<?> c) {
        implClass = c;
    }

    @Override
    public Object deserialize(JsonElement json, Type typeOfT, 
            JsonDeserializationContext context) throws JsonParseException {
        return context.deserialize(json, implClass);
    }
}

并且在杰克逊注册它就像一行

builder.registerTypeAdapter(A.class, new MyDeserializer(AImpl.class));
builder.registerTypeAdapter(B.class, new MyDeserializer(BImpl.class));

或者只使用lambda

builder.registerTypeAdapter(G.class, (JsonDeserializer) (json, typeOfT, context)
                -> context.deserialize(json, H.class));