英文:
JSON Deserialization exception with a Map<String,Map<String,Integer[]>>
问题
这个问题已经被 https://stackoverflow.com/users/218833/rnov 回答过了。
谢谢帮助!
我在编码一个可以将任何对象序列化为JSON的东西,我使用了一个 ```Map<String,Map<String, Integer[]>>``` 来处理属性... 基本上,如果你把那个映射命名为 ```map```,我应该能够通过 ```map.get("fields")``` 获取带有字段的映射,这将返回一个 ```Map<String, Integer[]>```... 这里的 ```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<String, Map<String, Integer[]>> 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<String,Map<String, Integer[]>>``` 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("fields")```, this will return a ```Map<String, Integer[]>```... 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'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
{
"fields":{
"hey" : [-84, -19, 0, 5, 116, 0, 4, 72, 101, 121, 33],
"u" : [-84, -19, 0, 5, 112]
}
}
The net.qava.util.UtilsParsedJson
class
public class UtilsParsedJson {
public Map<String, Map<String, Integer[]>> fields = null;
}
The JSON creator
default String createJson(){
String json = "{\n";
// Build Fields
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;
}
The JSON decoder
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;
}
}
Thanks for reading!
答案1
得分: 2
只需将Map<String, Map<String, Integer[]>> fields
更改为Map<String, Integer[]> fields
。您的fields
属性仅有一层嵌套。
或者,作为替代,您可以完全删除您的UtilsParsedJson
类,直接使用Map<String, Map<String, Integer[]>>
来替代它。
英文:
Just change Map<String, Map<String, Integer[]>> fields
to Map<String, Integer[]> fields
. Your fields
property has only one level of nesting.
Or, alternatively, you can remove your UtilsParsedJson
class altogether and just use Map<String, Map<String, Integer[]>>
instead of it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论