JSON路径结果中的通用列表类型

时间:2018-11-07 11:45:05

标签: java generics jsonpath

我想基于作为参数传递的泛型类,使用POJO序列化一些JSON。

Generic类应该扩展一个抽象类,以便我可以在结果数据结构上调用一些通用方法。

到目前为止,我已经知道了:

private <T extends TypeInterface> List<DBObject> getDataUsingJsonPath(String path, Class<T> type) {

    TypeRef<List<T>> typeRef = new TypeRef<List<T>>() {};

    Configuration configuration = Configuration
        .builder()
        .mappingProvider(new JacksonMappingProvider())
        .jsonProvider(new JacksonJsonProvider())
        .build();

    List<T> items = JsonPath.using(configuration).parse(jsonString).read(path, typeRef);

    result = items.getAggregations();

错误:

  

无法构造TypeInterface的实例,问题:抽象类型   要么需要映射到具体类型,要么具有自定义反序列化器,   或使用其他类型信息实例化

我试图告诉它扩展了TypeInterface,但是实际的Class是'type'...我在这里想念什么?

3 个答案:

答案 0 :(得分:1)

编译器将编译new TypeRef<List<T>>() {};作为对List<T extends TypeInterface>的引用,而不是type提供的元素类型。

JsonPath似乎不支持通过指定类进一步完善typeref。查看源代码,可以使用更扩展的库,例如guava,并进行以下修改:

  1. TypeToken<T>一样构造番石榴TypeRef<T>,但是使用.where(new TypeParameter<T>() {}, type)将类型变量精简为最终类型。
  2. 围绕新的typetoken创建包装器,该包装器为JsonPath提供精炼的类型:

包装器:

class TokenRef<T> extends TypeRef<T> {
    private final TypeToken<T> token;

    public TokenRef(TypeToken<T> token) {
        super();
        this.token = token;
    }

    @Override
    public Type getType() {
        return this.token.getType();
    }
}

答案 1 :(得分:1)

快速解决方案:

private <T extends TypeInterface> List<DBObject> getDataUsingJsonPath(String path, Class<T> type) {

    Configuration configuration = Configuration
        .builder()
        .mappingProvider(new JacksonMappingProvider())
        .jsonProvider(new JacksonJsonProvider())
        .build();

List<T> items = JsonPath.using(configuration).parse(jsonString).read(path, (Class<List<T>>) new ArrayList<T>().getClass());

这个想法是摆脱TypeRef<List<T>>的作用,但会发出警告。

答案 2 :(得分:0)

这里有一些很好的答案,但是经过一番睡眠后,我选择将TypeRef更改为实际参数。

private <T extends TypeInterface> List<DBObject> getDataUsingJsonPath(String path, TypeRef<List<T>> type) {

然后我可以按预期迭代结果:

List<T> items = JsonPath.using(configuration).parse(responseString).read(path, type);

for(T item : items) {
// do generic TypeInterface stuff here

我不知道这是否是最好的,最正确的“通用”方式,但是到目前为止还不错,并且在阅读我认为的代码时基本上是有意义的。