JSON反序列化异常,带有一个Map<String,Map<String,Integer[]>>。

huangapple go评论66阅读模式
英文:

JSON Deserialization exception with a Map<String,Map<String,Integer[]>>

问题

这个问题已经被 https://stackoverflow.com/users/218833/rnov 回答过了。
谢谢帮助!

我在编码一个可以将任何对象序列化为JSON的东西,我使用了一个 ```Map&lt;String,Map&lt;String, Integer[]&gt;&gt;``` 来处理属性... 基本上,如果你把那个映射命名为 ```map```,我应该能够通过 ```map.get(&quot;fields&quot;)``` 获取带有字段的映射,这将返回一个 ```Map&lt;String, Integer[]&gt;```... 这里的 ```String``` 是字段的名称,`Integer[]` 是在使用 ```ByteArrayOutputStream```  ```ObjectOutputStream``` 对对象进行序列化时输出的字节数组... 但由于某种原因,Jackson JSON解析器(版本2.2.3)(我也在使用Maven)在对整数数组进行反序列化时抛出以下异常:

**异常头部**
```com.fasterxml.jackson.databind.JsonMappingException: 无法从 START_ARRAY 令牌中反序列化 java.util.LinkedHashMap 实例```

**完整的异常信息(JSON文本除外,将在下面给出)**
```com.fasterxml.jackson.databind.JsonMappingException: 无法从 START_ARRAY 令牌中反序列化 java.util.LinkedHashMap 实例
 [Source: (String)"<JSON TEXT DOWN BELOW>"; 行: 3, 列: 9] 中(通过引用链: net.qava.util.UtilsParsedJson["fields"])```

**代码生成的 JSON 文本**
```json
{
"fields":{
"hey" : [-84, -19, 0, 5, 116, 0, 4, 72, 101, 121, 33],
"u" : [-84, -19, 0, 5, 112]
}
}

net.qava.util.UtilsParsedJson

public class UtilsParsedJson {
    public Map&lt;String, Map&lt;String, Integer[]&gt;&gt; fields = null;
}

JSON 创建器

default String createJson(){
        String json = "{" + "\n";

        // 构建字段
        json = json + "\"fields\":{" + "\n";

        for (Field field : this.getClass().getFields()){
            try {
                field.setAccessible(true);
                String name = field.getName();
                Object thing = field.get(this);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(thing);
                byte[] bytes = baos.toByteArray();
                json = json + "\"" + field.getName() + "\" : " + Arrays.toString(bytes) + "," + "\n";
            } catch (Exception e){
                e.printStackTrace();
            }
        }

        json = json.substring(0, json.length() - 2);

        json = json + "\n}\n}";

        System.out.println(json);

        return json;
    }

JSON 解码器

default UtilsJsonOutput decodeJson(String json){
        try {
            ObjectMapper mapper = new ObjectMapper();
            UtilsParsedJson upj = mapper.readValue(json, UtilsParsedJson.class);

            Map<String, Object> fields = new HashMap<>();
            for (Map.Entry<String, Integer[]> entry : (upj.fields.get("fields")).entrySet()){
                byte[] bytes = new byte[entry.getValue().length + 1];
                int p = 0;
                for (int i : entry.getValue()){
                    byte b = (byte) i;
                    bytes[p] = b;
                    p++;
                }

                ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
                ObjectInputStream ois = new ObjectInputStream(bais);
                Object object = ois.readObject();
                ois.close();
                bais.close();

                fields.put(entry.getKey(), object);
            }

            UtilsJsonOutput ups = new UtilsJsonOutput();
            ups.output.put("fields", fields);

            return ups;
        } catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

感谢阅读!


<details>
<summary>英文:</summary>

***This question has already been answered by 
https://stackoverflow.com/users/218833/rnov***
***Thanks for the help!***



I was coding something that can serialize any object into a JSON, and I used a ```Map&lt;String,Map&lt;String, Integer[]&gt;&gt;``` to do the properties... Basically, if you name that map ```map```, I should be able to get the map with the fields using ```map.get(&quot;fields&quot;)```, this will return a ```Map&lt;String, Integer[]&gt;```... The ```String``` is for the name of the field, the `Integer[]` is an array of bytes that where outputted when serializing the object using ```ByteArrayOutputStream``` and ```ObjectOutputStream```... But for some reason the Jackson JSON parser (Version 2.2.3) (I&#39;m also using Maven) throws this exception when it comes to deserializing the array of integers: 

**Exception Header**
```com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token```

**Whole Exception (Except the JSON text, that will be down below)**

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token
at [Source: (String)"<JSON TEXT DOWN BELOW>"; line: 3, column: 9] (through reference chain: net.qava.util.UtilsParsedJson["fields"])

**JSON Text generated by code.**
```json
{
&quot;fields&quot;:{
&quot;hey&quot; : [-84, -19, 0, 5, 116, 0, 4, 72, 101, 121, 33],
&quot;u&quot; : [-84, -19, 0, 5, 112]
}
}

The net.qava.util.UtilsParsedJson class

public class UtilsParsedJson {
    public Map&lt;String, Map&lt;String, Integer[]&gt;&gt; fields = null;
}

The JSON creator

default String createJson(){
        String json = &quot;{\n&quot;;

        // Build Fields
        json = json + &quot;\&quot;fields\&quot;:{\n&quot;;

        for (Field field : this.getClass().getFields()){
            try {
                field.setAccessible(true);
                String name = field.getName();
                Object thing = field.get(this);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(thing);
                byte[] bytes = baos.toByteArray();
                json = json+&quot;\&quot;&quot;+field.getName()+&quot;\&quot; : &quot;+Arrays.toString(bytes)+&quot;,\n&quot;;
            } catch (Exception e){
                e.printStackTrace();
            }
        }

        json = json.substring(0, json.length() - 2);

        json = json + &quot;\n}\n}&quot;;

        System.out.println(json);

        return json;
    }

The JSON decoder

default UtilsJsonOutput decodeJson(String json){
        try {
            ObjectMapper mapper = new ObjectMapper();
            UtilsParsedJson upj = mapper.readValue(json, UtilsParsedJson.class);

            Map&lt;String, Object&gt; fields = new HashMap&lt;&gt;();
            for (Map.Entry&lt;String, Integer[]&gt; entry : (upj.fields.get(&quot;fields&quot;)).entrySet()){
                byte[] bytes = new byte[entry.getValue().length + 1];
                int p=0;
                for (int i : entry.getValue()){
                    byte b = (byte) i;
                    bytes[p] = b;
                    p++;
                }

                ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
                ObjectInputStream ois = new ObjectInputStream(bais);
                Object object = ois.readObject();
                ois.close();
                bais.close();

                fields.put(entry.getKey(), object);
            }

            UtilsJsonOutput ups = new UtilsJsonOutput();
            ups.output.put(&quot;fields&quot;, fields);

            return ups;
        } catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

Thanks for reading!

答案1

得分: 2

只需将Map&lt;String, Map&lt;String, Integer[]&gt;&gt; fields更改为Map&lt;String, Integer[]&gt; fields。您的fields属性仅有一层嵌套。

或者,作为替代,您可以完全删除您的UtilsParsedJson类,直接使用Map&lt;String, Map&lt;String, Integer[]&gt;&gt;来替代它。

英文:

Just change Map&lt;String, Map&lt;String, Integer[]&gt;&gt; fields to Map&lt;String, Integer[]&gt; fields. Your fields property has only one level of nesting.

Or, alternatively, you can remove your UtilsParsedJson class altogether and just use Map&lt;String, Map&lt;String, Integer[]&gt;&gt; instead of it.

huangapple
  • 本文由 发表于 2020年10月12日 15:33:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/64313437.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定