[英]How can I transform a Map with a value of Object to the appropriate type?
I am working on a project where I need to accept a Map called properties
that is of type Map<String, Object>
.我正在开发一个项目,在该项目中我需要接受一个名为Map<String, Object>
类型的properties
的Map<String, Object>
。 There are going to be potentially many different keys in this Map
, but I only care about one: xpath
.此Map
可能有许多不同的键,但我只关心一个: xpath
。 An xpath
can have one of three different types of values: xpath
可以具有以下三种不同类型的值之一:
{"xpath": "path/to/xml/tag"}
一个字符串,例如{"xpath": "path/to/xml/tag"}
{"xpath": ["path/to/xml/tag1", "tag2", "path/tag3"}
{"xpath": ["path/to/xml/tag1", "tag2", "path/tag3"}
列表,例如: {"xpath": ["path/to/xml/tag1", "tag2", "path/tag3"}
Map<String, Map<String, Boolean>>
, such as:一个Map<String, Map<String, Boolean>>
,例如:{
"xpath":
{
"path/to/xml":
{
"setting1?": true,
"setting2?": true
},
"path/tag2":
{
"setting1?": false,
"setting2": true
},
"path/to/tag3": null
}
}
Now I have three variables: String xpath, Set<String> xpaths, Map<String, Map<String, boolean> xpathMap
.现在我有三个变量: String xpath, Set<String> xpaths, Map<String, Map<String, boolean> xpathMap
。 I have a function that is supposed to try and map the values of the "xpath"
key in the properties
map, and it looks like this:我有一个函数应该尝试映射properties
映射中"xpath"
键的值,它看起来像这样:
private void decideXPathType(Map<String, Object> properties)
{
Object propertiesXPath = properties.get("xpath");
if (propertiesXPath instanceof String)
{
this.xpath = (String) propertiesXPath;
} else if (propertiesXPath instanceof List)
{
this.xpaths = new HashSet<String>((List) propertiesXPath);
} else if (propertiesXPath instanceof Map)
{
for (Object key : ((Map) propertiesXPath).keySet())
{
Map<String, Boolean> value = (Map<String, Boolean>) ((Map) propertiesXPath).get(key);
this.xpathMap.put((String) key, value);
}
} else
{
throw new IllegalArgumentException("the xpath value is neither String, List, or Map<String, Boolean>");
}
}
But this function looks so bad - there is so much casting, etc - and although it works, it just looks too messy, and I imagine something can go wrong... any ideas on how I can make this cleaner?但是这个功能看起来很糟糕 - 有太多的演员等等 - 虽然它可以工作,但它看起来太乱了,我想可能会出错......关于如何使这个更清洁的任何想法?
Edit: Some more details编辑:更多细节
The properties
map is originally a json JsonNode requestBody
that I receive from a service. properties
映射最初是我从服务收到的 json JsonNode requestBody
。 Using ObjectMapper
, I create a properties
map as such:使用ObjectMapper
,我创建了一个properties
映射:
Map<String, Object> properties = new ObjectMapper().convertValue(new ObjectMapper().readTree(requestBody), new TypeReference<Map<String, Object>>(){});
If I receive a json string that is the value of the xpathMap
example that I gave, I get something that looks like this:如果我收到一个 json 字符串,它是我给出的xpathMap
示例的值,我会得到如下所示的内容:
Hope this information helps?希望这些信息有帮助?
In your JSON, use different keys for these different types of values: String
, List
and Map
.在您的 JSON 中,对这些不同类型的值使用不同的键: String
、 List
和Map
。 Deserializing a map:反序列化地图:
@Test
public void test0() throws IOException {
ObjectMapper om = new ObjectMapper();
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("xpath-object.json");
JsonNode jsonNode = om.readTree(inputStream);
Map<String, Map<String, Boolean>> value = om.readValue(jsonNode.get("xpath").toString(), Map.class);
// prints {path/to/xml={setting1?=true, setting2?=true}, path/to/tag3=null, path/tag2={setting1?=false, setting2=true}}
System.out.println(value);
}
If you need to work with 3rd party JSON, you can use following approach:如果您需要使用 3rd 方 JSON,您可以使用以下方法:
@Test
public void test() throws IOException {
testThemAll("xpath-scalar.json");
testThemAll("xpath-array.json");
testThemAll("xpath-object.json");
// prints:
// path/to/xml/tag
// [path/to/xml/tag1, tag2, path/tag3]
// {path/to/xml={setting1?=true, setting2?=true}, path/to/tag3=null, path/tag2={setting1?=false, setting2=true}}
}
private void testThemAll(String fileName) throws IOException {
ObjectMapper om = new ObjectMapper();
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(fileName);
JsonNode jsonNode = om.readTree(inputStream).get("xpath");
if (jsonNode.isValueNode())
System.out.println(jsonNode.asText());
else if (jsonNode.isArray()) {
System.out.println(om.readValue(jsonNode.toString(), List.class));
} else if (jsonNode.isObject()) {
Map<String, Map<String, Boolean>> value = om.readValue(jsonNode.toString(), Map.class);
System.out.println(value);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.