Java 使用Jackson将XML转换为映射,键应为小写
我正在尝试将XML字符串转换为映射,下面的代码转换得很好,但我需要映射键的统一方式(小写或大写)Java 使用Jackson将XML转换为映射,键应为小写,java,jackson,fasterxml,jackson-dataformat-xml,Java,Jackson,Fasterxml,Jackson Dataformat Xml,我正在尝试将XML字符串转换为映射,下面的代码转换得很好,但我需要映射键的统一方式(小写或大写) publicstaticvoidmain(字符串[]args)引发异常{ XmlMapper XmlMapper=新的XmlMapper(); setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE); 字符串xml=“1545391251168”; System.out.println(xmlMapper.readValue(xml.
publicstaticvoidmain(字符串[]args)引发异常{
XmlMapper XmlMapper=新的XmlMapper();
setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE);
字符串xml=“1545391251168”;
System.out.println(xmlMapper.readValue(xml.getBytes(),Map.class));
}
实际输出为:
{Status=Success,Result={Provider={lastUpdated=1545391251168}}
预期输出为:
{status=Success,result={provider={lastupdated=1545391251168}}
依赖关系:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.8</version>
</dependency>
com.fasterxml.jackson.core
杰克逊核心
2.9.8
com.fasterxml.jackson.dataformat
jackson数据格式xml
2.9.8
可能有更简单的方法,但如果其他方法都不起作用,您始终可以创建一个JsonDeserializer
。无论如何,我认为PropertyNamingStrategy
与如何将bean字段映射到xml/json有关,与map
键无关,但我可能错了。见下文:
public class LowerKeyDeserializer extends JsonDeserializer<Map<String, Object>> {
@Override
public Map<String, Object> deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
Map<String, Object> map = new HashMap<>();
JsonToken jsonToken;
String name = null;
while (null != (jsonToken = p.nextToken())) {
switch (jsonToken) {
case FIELD_NAME:
name = p.getText().toLowerCase(); // "magic" here
break;
case VALUE_STRING:
map.put(name, p.getText()); // value as it is
break;
case START_OBJECT: // and this will be a "sub"map, recursive call
map.put(name, deserialize(p, ctxt));
break;
default:
;
}
}
return map;
}
}
应打印:
{result={provider={lastupdated=1545391251168},status=Success}
如果映射到具有命名成员的pojo,NamingStrategy应该可以工作。看起来使用contaners有一些特殊的处理方法。对于您的用例,尝试实现一个自定义NamingStrategy(扩展PropertyNamingStrategy),它强制使用小写名称No。。我只需要一个映射,我不会去pojo..我的响应是动态的。但是它产生了另一个问题,
1545391251168CIMHttpGetRequestM7IH6HVWAAAAU74VJ5F5PBJZCIMHttpGetRequestM7IH6HwBAAAU74VJ7KW72FBCIMHttpGetRequestM7IH6HWCAAU74V4TQATY4
不按列表转换。上面的xml转换映射是:{result={provider={={lastupdated=1545391251168,连接={entitytype=CIMHTTPGETRequest,entityid=M7IH6Hvwaaau74VJ5F5PBJZ,连接={entitytype=CIMHTTPGETRequest,entityid=M7IH6HwBaaau74VJ7KW72FB,连接={entitytype=CIMHTTPGETRequest,entityid=M7IH6Hwcaau74V4Tqaty4}}}},状态=成功}
。这是错误的格式。我正在使用另一个用于列表引用的解析器@RajeshNarravula,我稍后会看一看。这可能是一个棘手的解析器,因为Collection
类型是在Pojo中显式配置的,带有注释,因此如果没有Pojo,甚至可能不可能。
public class LowerKeyDeserializer extends JsonDeserializer<Map<String, Object>> {
@Override
public Map<String, Object> deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
Map<String, Object> map = new HashMap<>();
JsonToken jsonToken;
String name = null;
while (null != (jsonToken = p.nextToken())) {
switch (jsonToken) {
case FIELD_NAME:
name = p.getText().toLowerCase(); // "magic" here
break;
case VALUE_STRING:
map.put(name, p.getText()); // value as it is
break;
case START_OBJECT: // and this will be a "sub"map, recursive call
map.put(name, deserialize(p, ctxt));
break;
default:
;
}
}
return map;
}
}
@Test
public void test() throws JsonParseException, JsonMappingException, IOException {
JacksonXmlModule xmlModule = new JacksonXmlModule();
xmlModule.addDeserializer(Map.class, new LowerKeyDeserializer());
XmlMapper xmlMapper = new XmlMapper(xmlModule);
String xml = "<Find Status=\"Success\"><Result><Provider><lastUpdated>1545391251168</lastUpdated></Provider></Result></Find>";
Map<?, ?> map = xmlMapper.readValue(xml.getBytes(), Map.class);
System.out.println(map);
}