Say*_*Pal 4 java serialization json jackson gson
我有类型的变量java.util.Properties。我正在尝试将其写入 JSON 文件,并从该文件中读取。
该Properties变量如下所示:
Properties inner3 = new Properties();
inner3.put("i1", 1);
inner3.put("i2", 100);
Properties inner2 = new Properties();
inner2.put("aStringProp", "aStringValue");
inner2.put("inner3", inner3);
Properties inner1 = new Properties();
inner1.put("aBoolProp", true);
inner1.put("inner2", inner2);
Properties topLevelProp = new Properties();
topLevelProp.put("count", 1000000);
topLevelProp.put("size", 1);
topLevelProp.put("inner1", inner1);
Run Code Online (Sandbox Code Playgroud)
当然,当我将 序列化为topLevelPropJSON 时,我希望结果如下所示。
{
"inner1": {
"inner2": {
"aStringProp": "aStringValue",
"inner3": {
"i2": 100,
"i1": 1
}
},
"aBoolProp": true
},
"size": 1,
"count": 1000000
}
Run Code Online (Sandbox Code Playgroud)
上面的 JSON 结果可以通过使用Gson以非常直接的方式生成,但是当它被馈送相同的 JSON 字符串进行反序列化时,它会失败。
Gson gson = new GsonBuilder().create();
String json = gson.toJson(topLevelProp); //{"inner1":{"inner2":{"aStringProp":"aStringValue","inner3":{"i2":100,"i1":1}},"aBoolProp":true},"size":1,"count":1000000}
//following line throws error: Expected a string but was BEGIN_OBJECT at line 1 column 12 path $.
Properties propObj = gson.fromJson(json, Properties.class);
Run Code Online (Sandbox Code Playgroud)
也与杰克逊一起尝试过:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
File file = new File("configs/config1.json");
mapper.writeValue(file, topLevelProp);
Run Code Online (Sandbox Code Playgroud)
最后一行抛出错误:
com.fasterxml.jackson.databind.JsonMappingException:java.util.Properties 不能转换为 java.lang.String(通过引用链:java.util.Properties["inner1"])
尝试从字符串反序列化如下,但失败并出现以下错误:
Properties jckProp = JsonSerializer.mapper.readValue(json, Properties.class);
Run Code Online (Sandbox Code Playgroud)
无法在 [Source: {"inner1":{"inner2":{"aStringProp":"aStringValue","inner3":{"i2":100,"i1 ":1}},"aBoolProp":true},"size":1,"count":1000000}; 行:1,列:11](通过引用链:java.util.Properties["inner1"])
如何处理?
更新:遵循cricket_007的想法, found com.fasterxml.jackson.databind.node.ObjectNode,可以如下使用:
ObjectNode jckProp = JsonSerializer.mapper.readValue(json, ObjectNode.class);
System.out.println(jckProp.get("size").asInt());
System.out.println("jckProp: " + jckProp);
System.out.println("jckProp.inner: " + jckProp.get("inner1"));
Run Code Online (Sandbox Code Playgroud)
我认为这对我来说可能是前进的方向,因为我主要必须从 JSON 文件中读取。
您遇到的问题是您误用了java.util.Properties:它不是多级树结构,而是简单的字符串到字符串映射。因此,虽然在技术上可能添加非字符串属性值(部分原因是这个类是在 Java 泛型之前添加的,这使得类型安全性更好),但不应该这样做。对于嵌套结构化,使用java.util.Map或特定的树数据结构。
至于Properties,javadocs 说例如:
The Properties class represents a persistent set of properties.
The Properties can be saved to a stream or loaded from a stream.
Each key and its corresponding value in the property list is a string.
...
If the store or save method is called on a "compromised" Properties
object that contains a non-String key or value, the call will fail.
Run Code Online (Sandbox Code Playgroud)
现在:如果你有这样的“妥协”Properties实例,你最好的选择是构建一个java.util.Map(或者可能是更旧的Hashtable),并序列化它。这应该没有问题。
| 归档时间: |
|
| 查看次数: |
12698 次 |
| 最近记录: |