Преобразование XML в карту с использованием Джексона, ключ должен быть в нижнем регистре - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь преобразовать строку XML в Map, ниже код хорошо конвертируется, но мне нужно, чтобы ключи карты были одинаковыми (строчные или прописные).

public static void main(String[] args) throws Exception {
  XmlMapper xmlMapper = new XmlMapper();
  xmlMapper.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE);
  String xml = "<Find Status=\"Success\"><Result><Provider><lastUpdated>1545391251168</lastUpdated></Provider></Result></Find>";
  System.out.println(xmlMapper.readValue(xml.getBytes(), Map.class));
} 

Фактический результат:

{Статус = Успех, Результат = {Провайдер = {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>

1 Ответ

0 голосов
/ 07 января 2019

Возможно, есть более простой способ сделать это, но если ничего не работает, вы всегда можете создать 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;
    }
}

Вам необходимо зарегистрироваться выше, используя JacksonXmlModule, см. Ниже:

@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);
}

Это должно вывести:

{результат = {поставщик = {lastupdated = 1545391251168}}, статус = успех}

...