Java Jackson和泛型类型引用

Java Jackson和泛型类型引用,java,json,generics,jackson,Java,Json,Generics,Jackson,我想将jackson json库用于以下通用方法: public MyRequest<T> tester() { TypeReference<MyWrapper<T>> typeRef = new TypeReference<MyWrapper<T>>(); MyWrapper<T> requestWrapper = (MyWrapper<T>) JsonConverter.fromJson(

我想将jackson json库用于以下通用方法:

public MyRequest<T> tester() {
    TypeReference<MyWrapper<T>> typeRef = new TypeReference<MyWrapper<T>>();  
    MyWrapper<T> requestWrapper = (MyWrapper<T>) JsonConverter.fromJson(jsonRequest, typeRef);
    return requestWrapper.getRequest();
}

现在的问题是,当我调用请求对象内部的getMyObject时,Jackson将嵌套的自定义对象作为LinkedHashMap返回。是否有任何方式可以指定T对象需要返回?例如:如果我发送了Customer类型的对象,那么应该从该列表返回Customer?

这是Java类型擦除的一个众所周知的问题:T只是一个类型变量,您必须指明实际的类,通常作为类参数。没有这些信息,最好的办法就是使用边界;普通的T和“T扩展对象”大致相同。然后Jackson将JSON对象绑定为映射

在这种情况下,tester方法需要具有类的访问权限,并且您可以构造

JavaType type = mapper.getTypeFactory().
  constructCollectionType(List.class, Foo.class)
然后

List<Foo> list = mapper.readValue(new File("input.json"), type);
“JavaType”很管用!! 我试图将json字符串中的列表反序列化为ArrayList java对象,从几天以来一直在努力寻找解决方案。 下面是最终为我提供解决方案的代码。 代码:

我修改了一个工作示例

JsonMarshaller.java 导入java.io.*; 导入java.util.*; 公共类JsonMarshaller{ 私有静态类加载器=JsonMarshaller.class.getClassLoader; 公共静态无效字符串[]args{ 试一试{ JsonMarshallerUnmarshaller marshaller=new-jsonmarshallerunmarshalerstation.class; 字符串jsonString=readloader.getResourceAsStreamdata.json; 列表站=marshaller.unmarshaljsonString; stations.forEachSystem.out::println; System.out.printlnmarshaller.Marshaller站; }捕捉异常{ e、 打印跟踪; } } @抑制警告资源 公共静态字符串readInputStream ios{ 返回新的Scannerios.useDelimiter\\A.next;//读取整个文件 } } 输出 JsonMarshallerUnmarshaller.java 导入java.io.*; 导入java.util.List; 导入com.fasterxml.jackson.core.*; 导入com.fasterxml.jackson.databind.*; 导入com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; 公共类JsonMarshallerUnmarshaller{ 私有对象映射器映射器; 私有类targetClass; 公共JsonMarshallerUnmarshallerClass targetClass{ AnnotationIntrospector内省器=新JacksonAnnotationIntrospector; 映射器=新对象映射器; mapper.getDeserializationConfig.withintrospector; mapper.getSerializationConfig.withintrospector; this.targetClass=targetClass; } 公共列表解组字符串jsonString抛出JsonParseException、JsonMappingException、IOException{ 返回parseListjsonString、mapper、targetClass; } 公共字符串封送处理列表引发JsonProcessingException{ 返回mapper.writeValueAsStringlist; } 公共静态列表parseListString str、ObjectMapper映射器、类clazz 抛出JsonParseException、JsonMappingException、IOException{ 返回mapper.readValuestr、listTypemapper、clazz; } 公共静态列表parseListInputStream是,ObjectMapper映射器,类clazz 抛出JsonParseException、JsonMappingException、IOException{ 返回mapper.readValueis、listTypemapper、clazz; } 公共静态JavaType listTypeObjectMapper映射器,类clazz{ 返回mapper.getTypeFactory.ConstructionCollectionTypeList.class,clazz; } } Station.java 公营电台{ 私人长id; 私有字符串标题; 私有字符串名称; 公共长getId{ 返回id; } 公共无效setIdlong id{ this.id=id; } 公共字符串getTitle{ 返回标题; } 公共无效设置标题字符串标题{ this.title=标题; } 公共字符串getName{ 返回名称; } public void setNameString名称{ this.name=名称; } @凌驾 公共字符串toString{ return String.formatStation[id=%s,title=%s,name=%s],id,title,name; } } data.json [{ id:123, 标题:我的标题, 姓名:我的名字 }, { 身份证号码:456, 标题:我的标题2, 姓名:我的名字2 }]
请添加gett的实现。这个问题类似于,但他们建议使用TypeFactory指定类型。但是我不知道编译时的类型…TypeFactory有不需要静态类的方法;createCollectionType等。请共享完整的代码。我也面临着同样的问题。TypeReference不是抽象的吗?它是有效的:我做了以下操作:JavaType topMost=mapper.getTypeFactory.ConstructParameterTypeMyWrapper.class,ActualClassRuntime.class;然后做了readValue,它终于起作用了:是的,确实起作用了-感谢您指出了创建泛型类型而不是映射/集合类型的方法@斯塔克斯曼:从现在起,用同学来做这类事情会更好吗?@husayt是的,从技术上讲是java classm
ate lib是优越的。但将它与Jackson集成有点棘手,因为Jackson自己的类型抽象是API的集成部分。从长远来看,找到合适的方法让Jackson使用同班代码,无论是嵌入的还是通过dep。我觉得Jackson不应该掩盖泛型中的漏洞,但不管怎样,它都做得很好。如何初始化TargetClass?请给我一个小例子。我正在传递类target,然后获取target.getClassName.Add一个构造函数,如下所示:JsonMarshallerUnmarshaller{private Class targetClass;JsonMarshallerUnmarshaller Class c{targetClass=c;}现在对“unmarshal”函数进行适当的更改,以使用该类,而不是在任何地方都执行getClass。注意事项:通过注意所有异常都是IOException的子类型,代码可以简化很多,只需一个捕获,默认的注释内省器已经是JacksonAnnotationIntrospector了,所以不需要对ObjectMapper做任何事情,只要构造它就可以了。所以我甚至都没有编译过这段代码。有没有要粘贴的实例?
JavaType type = mapper.getTypeFactory().
  constructCollectionType(List.class, Foo.class)
List<Foo> list = mapper.readValue(new File("input.json"), type);
JsonMarshallerUnmarshaller<T> {
    T targetClass;

    public ArrayList<T> unmarshal(String jsonString) {
        ObjectMapper mapper = new ObjectMapper();

        AnnotationIntrospector introspector = new JacksonAnnotationIntrospector();
        mapper.getDeserializationConfig()
            .withAnnotationIntrospector(introspector);

        mapper.getSerializationConfig()
            .withAnnotationIntrospector(introspector);
        JavaType type = mapper.getTypeFactory().
            constructCollectionType(
                ArrayList.class, 
                targetclass.getClass());

        try {
            Class c1 = this.targetclass.getClass();
            Class c2 = this.targetclass1.getClass();
            ArrayList<T> temp = (ArrayList<T>) 
                mapper.readValue(jsonString,  type);
            return temp ;
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null ;
    }  
}
Station [id=123, title=my title, name=my name]
Station [id=456, title=my title 2, name=my name 2]
[{"id":123,"title":"my title","name":"my name"},{"id":456,"title":"my title 2","name":"my name 2"}]