我有一个具有通用集合字段的类
class Test {
List<E> aList;
}
我想用杰克逊反序化这个。如何在不使用注释的情况下指定要用于此特定字段的集合类型,而不是对象中的所有列表(因为我无法更改现有类)。
我是杰克逊的初学者,所以我不知道如何编写自定义反序列化器。
答案 0 :(得分:1)
... FWIW
不使用注释(因为我无法更改现有的类)
Jackson's Mix-Ins feature可用于解决此问题。
我不知道如何编写自定义反序列化器
尽管与最新的杰克逊版本不完全一致,custom deserialization和custom creators上的杰克逊维基页面仍然相关。
此外,在Gson v Jackson - Part 3 on InstanceCreator for a Parameterized Type中,我针对类似问题发布了几种不同的解决方案。
答案 1 :(得分:0)
我认为你不需要做任何事杰克逊似乎能够弄清楚List的数据类型,我上周遇到了这个问题,结果发现Java Generic信息可以通过反射看到{ {3}}和What are the exceptions to type erasure in Java?
我编写了以下测试程序以更好地理解它。
public class GenericObject {
public Map<Integer,String> map = new HashMap<>();
private List<Integer> integers = new ArrayList<>();
private List<Date> dates = new ArrayList<>();
public List<Integer> getIntegers() {
return integers;
}
public void setIntegers(List<Integer> integers) {
this.integers = integers;
}
public List<Date> getDates() {
return dates;
}
public void setDates(List<Date> dates) {
this.dates = dates;
}
public void setIntegersList(Integer... ints)
{
for (Integer integer : ints) {
integers.add(integer);
}
}
public void setDatesList(Date... dates)
{
for (Date date : dates) {
this.dates.add(date);
}
}
public void runtimeGenericTypes()
{
try {
Field field = GenericObject.class.getField("map");
System.out.println("Field has type " + field.getType());
ParameterizedType genericType = (ParameterizedType) field.getGenericType();
Type[] actualTypeArguments2 = genericType.getActualTypeArguments();
for (Type type : actualTypeArguments2) {
System.out.println("Gerenic field types: " + type);
}
// get the return type of a generic method
Method method =GenericObject.class.getMethod("getIntegers",null);
Class<?> returnType = method.getReturnType();
System.out.println(returnType);
Type genericReturnType = method.getGenericReturnType();
ParameterizedType parameterizedType = (ParameterizedType) genericReturnType;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
for (Type type : actualTypeArguments) {
System.out.println(type);
}
System.out.println(genericReturnType);
// get the parameter type of a generic method
Method set = GenericObject.class.getMethod("setIntegers", List.class);
Class<?>[] parameterTypes = set.getParameterTypes();
for (Class<?> class1 : parameterTypes) {
System.out.println("Parameter type " + class1);
}
Type[] genericParameterTypes = set.getGenericParameterTypes();
for (Type type : genericParameterTypes) {
ParameterizedType parameterizedType2 = (ParameterizedType) type;
parameterizedType2.getActualTypeArguments();
for (Type type2 : genericParameterTypes) {
System.out.println(" Paratermer type is: " + type2);
}
}
} catch (SecurityException | NoSuchMethodException | NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
TypeVariable<?>[] typeParameters = dates.getClass().getTypeParameters();
for (TypeVariable<?> typeVariable : typeParameters) {
System.out.println(typeVariable);
}
}
public static void main(String[] args) {
GenericObject object = new GenericObject();
object.setIntegersList(1,2,4,5,5);
object.setDatesList(new Date());
object.runtimeGenericTypes();
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT,true);
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
mapper.setDateFormat(df);
String json;
try {
json = mapper.writeValueAsString(object);
System.out.println(json);
GenericObject readObject = mapper.readValue(json, GenericObject.class);
List<Integer> readIntegers = readObject.getIntegers();
for (Integer integer : readIntegers) {
System.out.println(integer);
}
List<Date> dates2 = readObject.getDates();
for (Date date : dates2) {
System.out.println(date);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}