1

我有一个具有通用集合字段的类

class Test {
  List<E> aList;
}

我想使用杰克逊反序列化它。如何在不使用注释的情况下指定用于此特定字段的集合类型,而不是对象中的所有列表(因为我无法更改现有类)。

我是杰克逊的初学者,所以我不知道如何编写自定义反序列化器。

4

2 回答 2

1

FWIW...

不使用注释(因为我无法更改现有类)

Jackson 的 Mix-Ins 功能可用于解决此问题。

我不知道如何编写自定义反序列化器

尽管没有完全更新最新的 Jackson 版本,但 Jackson Wiki 页面上关于自定义反序列化和自定义创建者的页面仍然相关。

此外,在Gson v Jackson - Part 3 on InstanceCreator for a Parameterized Type中,我针对类似问题发布了几个不同的解决方案。

于 2012-08-08T16:28:41.920 回答
0

我认为您不需要做任何事情 Jackson 似乎能够弄清楚 List 的数据类型,我上周遇到了这个问题,结果证明 Java Generic 信息可以通过反射获得,请参阅有什么例外在 Java 中键入擦除?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();
        }


}

}

于 2012-08-08T09:34:24.787 回答