Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.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
用Jackson反序列化Java数组_Java_Json_Serialization_Jackson - Fatal编程技术网

用Jackson反序列化Java数组

用Jackson反序列化Java数组,java,json,serialization,jackson,Java,Json,Serialization,Jackson,我尝试将Jackson用作通用序列化引擎,而不是Java序列化。 通过以下方式初始化映射器: objectMapper = new ObjectMapper(); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 中的所有类型信息都存储在JSON中,因此我可以通过以下方式写入和读取所有对象: objectMapper.readValue(json, Object.class) 我在尝试序列化然后反序

我尝试将Jackson用作通用序列化引擎,而不是Java序列化。 通过以下方式初始化映射器:

objectMapper = new ObjectMapper();
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
中的所有类型信息都存储在JSON中,因此我可以通过以下方式写入和读取所有对象:

objectMapper.readValue(json, Object.class)
我在尝试序列化然后反序列化java数组时遇到了问题。 由于Jackson没有将数组类型存储到JSON中,因此在反序列化阶段会失败。在以下代码中:

    String [] strings = {"A", "B", "C"};
    try {
        String json = objectMapper.writeValueAsString(strings);
        String [] stringsBack = (String [])objectMapper.readValue(json, Object.class);
        if (!strings.equals(stringsBack)) {
            System.err.println("ERROR, stringsBack not the same!!!\n\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
json将被设置为“[“A”、“B”、“C”]”,但在反序列化时,我得到以下异常:

Exception in thread "main" java.lang.IllegalArgumentException: Invalid type id 'A' (for id type 'Id.class'): no such class found
at com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver._typeFromId(ClassNameIdResolver.java:66)
at com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver.typeFromId(ClassNameIdResolver.java:48)
at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._findDeserializer(TypeDeserializerBase.java:157)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:94)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromAny(AsArrayTypeDeserializer.java:68)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserializeWithType(UntypedObjectDeserializer.java:494)
at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:42)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3560)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2576)
at Main.run(Main.java:86)
有没有一种方法可以指示Jackson将java数组类型信息存储到JSON中?
我的序列化引擎是泛型的,事先不知道它将从JSON字符串中读取的类型。

目前我找到的最佳解决方案是在序列化之前检查对象是否是数组(Class.isArray),然后执行序列化:

TypeReference ref = new TypeReference<List[]>() { };
String json = objectMapper.writerFor(ref).writeValueAsString(strings);
TypeReference=newtypereference(){};
String json=objectMapper.writerFor(ref).writeValueAsString(String);

这将把数组类型添加到JSON中,并允许读取它。

目前我找到的最佳解决方案是在序列化之前检查对象是否是数组(Class.isArray),然后执行序列化:

TypeReference ref = new TypeReference<List[]>() { };
String json = objectMapper.writerFor(ref).writeValueAsString(strings);
TypeReference=newtypereference(){};
String json=objectMapper.writerFor(ref).writeValueAsString(String);
这将把数组类型添加到JSON中,并允许将其读回。

正确的方法是:

String[] strings = { "A", "B", "C" };
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(strings);
List<String> data = mapper.readValue(json,
        mapper.getTypeFactory().constructCollectionType(List.class, String.class));
for (String string : data) {
    System.out.println(string);
}
String[]strings={“A”、“B”、“C”};
ObjectMapper mapper=新的ObjectMapper();
String json=mapper.writeValueAsString(字符串);
List data=mapper.readValue(json,
getTypeFactory().ConstructionCollectionType(List.class,String.class));
for(字符串:数据){
System.out.println(字符串);
}
正确的方法是:

String[] strings = { "A", "B", "C" };
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(strings);
List<String> data = mapper.readValue(json,
        mapper.getTypeFactory().constructCollectionType(List.class, String.class));
for (String string : data) {
    System.out.println(string);
}
String[]strings={“A”、“B”、“C”};
ObjectMapper mapper=新的ObjectMapper();
String json=mapper.writeValueAsString(字符串);
List data=mapper.readValue(json,
getTypeFactory().ConstructionCollectionType(List.class,String.class));
for(字符串:数据){
System.out.println(字符串);
}

代码存在多个问题

1) 首先让我们看看为什么会有例外

Exception in thread "main" java.lang.IllegalArgumentException: Invalid type id 'A' (for id type 'Id.class'): no such class found 
上面的错误表示它没有找到某个类,并将A引用为无效的类型id“A”,这似乎是Json中的一个问题

这个问题是因为台词

objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
这为所有非最终类型启用了默认类型。默认类型使用对象的实际值打印对象的类型,从而允许反序列化为同一类型。声明它为NON_FINAL不会添加诸如String之类的“自然”类型

现在,当反序列化Json[“A”、“B”、“C”]时,反序列化程序不知道Json也要转换成什么对象,并将A作为类类型,试图找到它没有得到的类

2) 注释第一行可能会产生ClassCastException,因为

objectMapper.readValue(json, Object.class);
将返回ArrayList的对象,但无法将其转换为字符串[]

3)
!strings.equals(stringsBack)
将始终返回true,因为strings和stringsBack都是String[]的不同对象

更正以下代码中的所有内容将起作用

    ObjectMapper objectMapper = new ObjectMapper();
    //You can remove the below line if Default Typing is not Required.  
    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    String[] strings = { "A", "B", "C" };
    try
    {
        String json = objectMapper.writeValueAsString(strings);
        System.out.println(json);
        String[] stringsBack = (String[]) objectMapper.readValue(json, new TypeReference<String[]>()
        {});
        if (!Arrays.equals(strings, stringsBack))
        {
            System.err.println("ERROR, stringsBack not the same!!!\n\n");
        }
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
ObjectMapper ObjectMapper=new ObjectMapper();
//如果不需要默认键入,可以删除下面的行。
objectMapper.enableDefaultTyping(objectMapper.DefaultTyping.NON_FINAL);
String[]strings={“A”、“B”、“C”};
尝试
{
String json=objectMapper.writeValueAsString(字符串);
System.out.println(json);
String[]stringsBack=(String[])objectMapper.readValue(json,新类型引用()
{});
如果(!array.equals(strings,stringsBack))
{
System.err.println(“错误,stringsBack不一样!!!\n\n”);
}
}
捕获(IOE异常)
{
e、 printStackTrace();
}

代码存在多个问题

1) 首先让我们看看为什么会有例外

Exception in thread "main" java.lang.IllegalArgumentException: Invalid type id 'A' (for id type 'Id.class'): no such class found 
上面的错误表示它没有找到某个类,并将A引用为无效的类型id“A”,这似乎是Json中的一个问题

这个问题是因为台词

objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
这为所有非最终类型启用了默认类型。默认类型使用对象的实际值打印对象的类型,从而允许反序列化为同一类型。声明它为NON_FINAL不会添加诸如String之类的“自然”类型

现在,当反序列化Json[“A”、“B”、“C”]时,反序列化程序不知道Json也要转换成什么对象,并将A作为类类型,试图找到它没有得到的类

2) 注释第一行可能会产生ClassCastException,因为

objectMapper.readValue(json, Object.class);
将返回ArrayList的对象,但无法将其转换为字符串[]

3)
!strings.equals(stringsBack)
将始终返回true,因为strings和stringsBack都是String[]的不同对象

更正以下代码中的所有内容将起作用

    ObjectMapper objectMapper = new ObjectMapper();
    //You can remove the below line if Default Typing is not Required.  
    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    String[] strings = { "A", "B", "C" };
    try
    {
        String json = objectMapper.writeValueAsString(strings);
        System.out.println(json);
        String[] stringsBack = (String[]) objectMapper.readValue(json, new TypeReference<String[]>()
        {});
        if (!Arrays.equals(strings, stringsBack))
        {
            System.err.println("ERROR, stringsBack not the same!!!\n\n");
        }
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
ObjectMapper ObjectMapper=new ObjectMapper();
//如果不需要默认键入,可以删除下面的行。
objectMapper.enableDefaultTyping(objectMapper.DefaultTyping.NON_FINAL);
String[]strings={“A”、“B”、“C”};
尝试
{
String json=objectMapper.writeValueAsString(字符串);
System.out.println(json);
String[]stringsBack=(String[])objectMapper.readValue(json,新类型引用()
{});
如果(!array.equals(strings,stringsBack))
{
System.err.println(“错误,stringsBack不一样!!!\n\n”);
}
}
捕获(IOE异常)
{
e、 printStackTrace();
}

是否有不使用
objectMapper.readValue(json,String[].class)的原因?你告诉Jackson去反序列化一个对象,当然它不知道是什么类型的对象