Java 使用Jackson将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.

我正在尝试将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);
}