【问题标题】:Using Jackson ObjectMapper with Generics to POJO instead of LinkedHashMap使用带有泛型的 Jackson ObjectMapper 到 POJO 而不是 LinkedHashMap
【发布时间】:2012-02-12 19:15:09
【问题描述】:

我正在使用 Jersey 定义如下服务:

@Path("/studentIds")
public void writeList(JsonArray<Long> studentIds){
 //iterate over studentIds and save them
}

JsonArray 在哪里:

public class JsonArray<T> extends ArrayList<T> {  
    public JsonArray(String v) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper(new MappingJsonFactory());
        TypeReference<ArrayList<T>> typeRef = new TypeReference<ArrayList<T>>() {};
        ArrayList<T> list = objectMapper.readValue(v, typeRef);
        for (T x : list) {
            this.add((T) x);
        }
    }
}

这很好用,但是当我做一些更复杂的事情时:

@Path("/studentIds")
public void writeList(JsonArray<TypeIdentifier> studentIds){
 //iterate over studentIds and save them by type
}

这里的 Bean 是一个简单的 POJO,例如

public class TypeIdentifier {
    private String type;
    private Long id;
//getters/setters 
}

整个事情都糟糕透了。它将所有内容都转换为 LinkedHashMap 而不是实际的对象。如果我手动创建一个类,我可以让它工作:

public class JsonArrayTypeIdentifier extends ArrayList<TypeIdentifier> { 
    public JsonArrayTypeIdentifier(String v) throws IOException  {
        ObjectMapper objectMapper = new ObjectMapper(new MappingJsonFactory());
        TypeReference<ArrayList<TypeIdentifier>> typeRef = new TypeReference<ArrayList<TypeIdentifier>>(){};
        ArrayList<TypeIdentifier> list = objectMapper.readValue(v, typeRef);
        for(TypeIdentifier x : list){
            this.add((TypeIdentifier) x);
        }
    }
 }

但我试图在不添加额外的类的情况下保持这种良好和通用性。为什么只有通用版本会发生这种情况?

【问题讨论】:

标签: java json jersey jackson


【解决方案1】:

首先,它适用于 Longs,因为这是一种原生类型,因此是 JSON 整数的默认绑定。

但是至于为什么没有正确传递泛型类型信息:这很可能是由于 JAX-RS API 将类型传递给MessageBodyReaders 和MessageBodyWriters 的方式存在问题——传递java.lang.reflect.Type 不是(不幸的是!)足以通过实际的泛型声明(有关这方面的更多信息,请阅读this blog entry)。

一个简单的解决方法是创建辅助类型,例如:

class MyTypeIdentifierArray extends JsonArray<TypeIdentifier> { }

并使用该类型——一切都会“正常工作”,因为始终保留超类型通用信息。

【讨论】:

  • 您的解决方法不起作用。 :( 仍然给我 LinkedHashMap 作为解析结果。回到我长期的解决方法。叹息。
  • 它肯定可以工作——你能告诉我你是如何解析它们的吗? LinkedHashMap 仅在缺少类型信息时返回(或者如果Object.class 被定义为类型)。这是哪个 Jackson 版本的?
  • JsonArray 类 is 正是我试图解析它们的方式。此类返回的是 LinkedHashMap 列表。如果我使用 JsonArrayTypeIdentifier,那么它会返回一个 TypeIdentifier 列表。
  • 您是否完整阅读了我的回复?我建议你应该使用它的子类(MyTypeIdentifierArray)而不是直接使用JsonArray——问题可能来自于 Jersey 没有传递所有必要的类型信息。您可以先直接使用 ObjectMapper 来验证这一点;这确实应该有效。
  • 是的。 Jackson 无能为力:JAX-RS 规范在泛型类型传递方面存在缺陷。
猜你喜欢
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多