我在Java中有一些类要转换为Map<String, String>
。问题是,我的java类中没有明显String
表示(集合,其他类)的任何字段都应转换为json字符串。
以下是一个例子:
@Data
@AllArgsConstructor
class MyClass {
String field1;
Long field2;
Set<String> field3;
OtherClass field4;
}
@Data
@AllArgsConstructor
class OtherClass {
String field1;
String field2;
}
ObjectMapper mapper = new ObjectMapper();
MyClass myClass = new MyClass("value",
123L,
Sets.newHashSet("item1", "item2"),
new OtherClass("value1", "value2"));
Map<String, String> converted =
mapper.convertValue(myClass, new TypeReference<Map<String, String>>(){});
此时,converted
应如下所示:
"field1" -> "value"
"field2" -> "123"
"field3" -> "[\"item1\", \"item2\"]"
"field4" -> "{\"field1\":\"value1\",\"field2\":\"value2\"}"
相反,当尝试使用例外mapper.convertValue
取消定义Set时,对java.lang.IllegalArgumentException: Can not deserialize instance of java.lang.String out of START_ARRAY token
的调用失败。
是否有任何特殊配置我可以使用MyClass
注释或配置ObjectMapper
以使其按照我希望的方式工作?
答案 0 :(得分:0)
这是一种方法。
private static final ObjectMapper mapper = new ObjectMapper();
public Map<String, String> toMap(Object obj) {
// Convert the object to an intermediate form (map of strings to JSON nodes)
Map<String, JsonNode> intermediateMap = mapper.convertValue(obj, new TypeReference<Map<String, JsonNode>>() {});
// Convert the json nodes to strings
Map<String, String> finalMap = new HashMap<>(intermediateMap.size() + 1); // Start out big enough to prevent resizing
for (Map.Entry<String, JsonNode> e : intermediateMap.entrySet()) {
String key = e.getKey();
JsonNode val = e.getValue();
// Get the text value of textual nodes, and convert non-textual nodes to JSON strings
String stringVal = val.isTextual() ? val.textValue() : val.toString();
finalMap.put(key, stringVal);
}
return finalMap;
}
如果你想转换Map&lt; String,String&gt;回到原来的班级......
public static <T> T fromMap(Map<String, String> map, Class<T> clazz) throws IOException {
// Convert the data to a map of strings to JSON nodes
Map<String, JsonNode> intermediateMap = new HashMap<>(map.size() + 1); // Start out big enough to prevent resizing
for (Map.Entry<String, String> e : map.entrySet()) {
String key = e.getKey();
String val = e.getValue();
// Convert the value to the right type of JsonNode
JsonNode jsonVal;
if (val.startsWith("{") || val.startsWith("[") || "null".equals(val)) {
jsonVal = mapper.readValue(val, JsonNode.class);
} else {
jsonVal = mapper.convertValue(val, JsonNode.class);
}
intermediateMap.put(key, jsonVal);
}
// Convert the intermediate map to an object
T result = mapper.convertValue(intermediateMap, clazz);
return result;
}