Java Jackson和泛型类型引用
我想将jackson json库用于以下通用方法: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(
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"}]