Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jackson泛型类型引用+;启用默认类型问题_Java_Json_Generics_Jackson - Fatal编程技术网

Java Jackson泛型类型引用+;启用默认类型问题

Java Jackson泛型类型引用+;启用默认类型问题,java,json,generics,jackson,Java,Json,Generics,Jackson,在同时使用enableDefaultTyping和提供泛型TypeReference时,我遇到了反序列化问题。杰克逊似乎无法决定哪种类型的信息更重要。此测试用例正在演示问题: @Test public void roundTripTest() throws JsonGenerationException, JsonMappingException, IOException { // 0 Value Test Integer[] integers = new In

在同时使用enableDefaultTyping和提供泛型TypeReference时,我遇到了反序列化问题。杰克逊似乎无法决定哪种类型的信息更重要。此测试用例正在演示问题:

@Test
public void roundTripTest() throws JsonGenerationException,
        JsonMappingException, IOException {

    // 0 Value Test
    Integer[] integers = new Integer[] {};
    Wrap<Integer[]> beforeResult = new Wrap<Integer[]>(integers);

    File file = new File("/tmp/jsonTest");
    mapper.writeValue(file, beforeResult);

    TypeReference<Wrap<Integer[]>> typeRef = new TypeReference<JacksonMapperTest.Wrap<Integer[]>>() {
    };

    Wrap<Integer[]> afterResult = mapper.readValue(file, typeRef);

    assertNotNull(afterResult);

}


public static class Wrap<T> {

    private T wrapped;

    public Wrap() {
    }

    public Wrap(T wrapped) {
        this.wrapped = wrapped;
    }

    public T getWrapped() {
        return wrapped;
    }

    public void setWrapped(T wrapped) {
        this.wrapped = wrapped;
    }
}
例外情况是:

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class JacksonMapperTest$Wrap<[Ljava.lang.Integer;>]: can not instantiate from JSON object (need to add/enable type information?)
org.codehaus.jackson.map.JsonMappingException:找不到适合类型[simple type,class JacksonMapperTest$Wrap]的构造函数:无法从JSON对象实例化(需要添加/启用类型信息?)
很奇怪吧?通过使用beforeResult.getClass而不是TypeReference,可以忽略该问题,但它仍然不是首选行为

我是否错过了解决这个问题的任何选择

我用的是杰克逊1.9.3

[编辑]
使用贴图而不是数组作为包装对象的效果与预期一样

这似乎是杰克逊的一个缺陷…然而,它的作者可能更能分辨它是否是一个bug。。。如果你可以自由地从杰克逊那里换衣服,看看根森

Gensons与enableDefaultTyping等价的是setUseRuntimeTypeForSerialization(不完全相同,但在大多数情况下非常相似)。它在序列化期间使用运行时类型。以下是一个例子:

Genson genson = new Genson.Builder().setUseRuntimeTypeForSerialization(true).create();
String json = genson.serialize(beforeResult);
System.out.println(json);
GenericType<Wrap<Integer[]>> type = new GenericType<Wrap<Integer[]>>() {};
Wrap<Integer[]> afterResult = genson.deserialize(json, type);
Genson Genson=new Genson.Builder().setUseRuntimeTypeForSerialization(true.create();
字符串json=genson.serialize(beforeResult);
System.out.println(json);
GenericType类型=新的GenericType(){};
Wrap afterResult=genson.deserialize(json,类型);
编辑
如果您需要能够使用genson反序列化为polymoprhic或未知类型,请使用genson.Builder的setWithClassMetadata(true)。此功能实际上仅用于json对象(无论它是否为抽象类)。

我不能100%确定确切的根本原因,但我怀疑这与Java类型擦除以及传递泛型感知信息和将其与默认类型信息混合的问题有关。类型信息实际上仅基于非泛型类型;但是,它确实适用于特定类型的泛型类型(映射、集合)

但在这种情况下,您有自定义泛型类型;我认为这就是为什么Jackson不能为动态类型的目的指出属性的泛型类型

通常的解决方法是尽可能尝试细分;但幸运的是,你找到了一个更好的解决办法

Genson genson = new Genson.Builder().setUseRuntimeTypeForSerialization(true).create();
String json = genson.serialize(beforeResult);
System.out.println(json);
GenericType<Wrap<Integer[]>> type = new GenericType<Wrap<Integer[]>>() {};
Wrap<Integer[]> afterResult = genson.deserialize(json, type);