gpt4 book ai didi

java - 在 Map 上进行未经检查的转换(使用 Jackson 将 JSON 转换为 Map)

转载 作者:行者123 更新时间:2023-11-30 10:05:26 25 4
gpt4 key购买 nike

在 Java 8 中,我想将 JSON 字符串转换为映射,并对键应用“复杂”转换。 例如,“复杂”转换将只是一个小写转换。输入 JSON 中的值可以是字符串或嵌套的 JSON 对象。我的代码确实有效,但我很难修复 unchecked cast警告。

例子

示例 JSON 输入 ( String) :

{
"Key1": "value1",
"Key2": {
"Key2.1": "value2.1"
}
}

期望的输出(Map):

"key1" -> "value1"
"key2" ->
"key2.1" -> "value2.1"

1。 JSON 字符串 -> map

对于那部分,我使用了 Jackson (2.9.8) 并定义了以下函数:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

Map<String, Object> convertJsonStringToMap(String json) throws IOException {
ObjectMapper mapper = new ObjectMapper();
TypeReference type = new TypeReference<Map<String, Object>>(){};
return mapper.readValue(json, type);
}

由于值可以是字符串或 JSON 对象,该函数的返回类型是 Map<String, Object> .还要注意的是 readValue (在 ObjectMapper 类中)使用泛型,它的签名是:

<T> T readValue(String content, TypeReference valueTypeRef)

2。 Map -> Map with transformed keys (example : lower case)

我定义了以下函数:

Map<String, Object> transformKeys(Map<String, Object> map) {
Map<String, Object> result = new HashMap<>(map.size());

for (Map.Entry<String, Object> entry : map.entrySet()) {
Object value = entry.getValue();
if (value instanceof Map) {
value = transformKeys((Map<String, Object>) value);
}
// toLowerCase() is the transformation here (example), but I could have used something else
result.put(entry.getKey().toLowerCase(), value);
}

return result;
}

为了处理嵌套 map ,这个函数是递归的。但是因为它需要 Map<String, Object>作为参数, 我必须投valueMap<String, Object>递归调用方法。

3。放在一起

String json = "{\"Key1\": \"value1\", \"Key2\": { \"Key2.1\": \"value2.1\" }}";
Map<String, Object> initialMap = convertJsonStringToMap(json);
Map transformedMap = transformKeys(initialMap);
System.out.println(transformedMap);

此代码按预期工作并打印:

{key1=value1, key2={key2.1=value2.1}}

但是transformKeys中的这一行功能:

value = transformKeys((Map<String, Object>) value);

产生警告:

[WARNING] App.java:[29,74] unchecked cast
required: java.util.Map<java.lang.String,java.lang.Object>
found: java.lang.Object

警告很清楚,我理解(编译器无法知道 value 是否真的是 Map<String, Object> 的实例),但有没有办法摆脱它?

(请不要 @SuppressWarnings,也不要 -Xlint:none):D

我想返回 Map<String, Object>来自 convertJsonStringToMap是这不是将 JSON String 转换为 Map 的最干净的方法,但我找不到其他方法来使用 Jackson。

最佳答案

您需要使用 Object 作为 Map 值,因为它可能是另一个 MapList原始(StringInteger 等)。 Jackson 还允许使用 JsonNode 类型来操作 JSON。我们需要遍历 JSON 对象,还需要遍历 JSON 数组(你忘记了)。在这种情况下,我们需要:

  • JSON 反序列化为 JsonNode
  • 使用 JsonNode API 遍历它。
  • 转换为 map

简单的实现:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class JsonApp {

public static void main(String[] args) throws Exception {
String json = "{\"Key1\": \"value1\", \"Key2\": { \"Key2.1\": \"value2.1\" }, \"Key3\":[{\"pRiMe\":11}]}";
Map<String, Object> map = convertJsonStringToMap(json);

System.out.println(map);
}

private static Map<String, Object> convertJsonStringToMap(String json) throws IOException {
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(json);
transformKeys(node);

TypeReference mapType = new TypeReference<Map<String, Object>>() {
};

return mapper.convertValue(node, mapType);
}

private static void transformKeys(JsonNode parent) {
if (parent.isObject()) {
ObjectNode node = (ObjectNode) parent;

List<String> names = new ArrayList<>();
node.fieldNames().forEachRemaining(names::add);

names.forEach(name -> {
JsonNode item = node.remove(name);
transformKeys(item);
node.replace(name.toLowerCase(), item);
});
} else if (parent.isArray()) {
ArrayNode array = (ArrayNode) parent;
array.elements().forEachRemaining(JsonApp::transformKeys);
}
}
}

以上代码打印:

{key1=value1, key2={key2.1=value2.1}, key3=[{prime=11}]}

我们摆脱了不安全的转换,我们的实现更加简洁。

关于java - 在 Map<String, Object> 上进行未经检查的转换(使用 Jackson 将 JSON 转换为 Map),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55261039/

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