gpt4 book ai didi

java - 如何将 java.util.Properties 与 JSON 文件序列化?

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:40:11 24 4
gpt4 key购买 nike

我有 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);

当然,当我将 topLevelProp 序列化为 JSON 时,我希望结果如下所示。

{
"inner1": {
"inner2": {
"aStringProp": "aStringValue",
"inner3": {
"i2": 100,
"i1": 1
}
},
"aBoolProp": true
},
"size": 1,
"count": 1000000
}

上述 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);

也试过 jackson :

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);

最后一行抛出错误:

com.fasterxml.jackson.databind.JsonMappingException: java.util.Properties cannot be cast to java.lang.String (through reference chain: java.util.Properties["inner1"])

尝试从字符串反序列化如下,但失败并出现以下错误:

Properties jckProp = JsonSerializer.mapper.readValue(json, Properties.class);

Can not deserialize instance of java.lang.String out of START_OBJECT token at [Source: {"inner1":{"inner2":{"aStringProp":"aStringValue","inner3":{"i2":100,"i1":1}},"aBoolProp":true},"size":1,"count":1000000}; line: 1, column: 11] (through reference chain: java.util.Properties["inner1"])

如何处理?

更新:idea of cricket_007之后,找到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"));

我认为这可能是我前进的方向,因为我大部分时间都必须从 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.

现在:如果当你有这样的“妥协的”Properties 实例时,你使用 Jackson 或 Gson 的最佳选择是构建一个 java.util.Map(或者也许older Hashtable),并将其序列化。这应该没有问题。

关于java - 如何将 java.util.Properties 与 JSON 文件序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41730115/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com