1

I have a class which has a generic collection field

class Test {
  List<E> aList;
}

I want to deserialize this using Jackson. How can i specify the type of collection to use for this specific field, not for all lists in the object, without using annotations (as I cannot change the existing class).

I am a beginner in Jackson, so i don't know how to write a custom deserializer.

4

2 に答える 2

1

ふぅ…

注釈を使用せずに(既存のクラスを変更できないため)

Jackson の Mix-Ins 機能を使用すると、この問題を回避できます。

カスタムデシリアライザーの書き方がわからない

最新の Jackson リリースでは完全に最新ではありませんが、カスタム デシリアライゼーションカスタム クリエーターに関する Jackson Wiki ページは引き続き関連しています。

また、Gson v Jackson - InstanceCreator for a Parameterized Type のパート 3 では、同様の問題に対するいくつかの異なる解決策を投稿しました。

于 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 に答える