Исключение Джексона при синтаксическом анализе Yaml с отображением значений списка

#java #jackson #yaml #dropwizard

#java #джексон #yaml #dropwizard

Вопрос:

У меня есть документ Yaml, который включает записи карты, соответствующие спискам. Вот пример:

 environments:
  qa: [ 'us-east-1' ]
  staging: [ 'us-east-1', 'us-west-2' ]
 

Я использую Jackson 2.3.2 для разбора документа в класс, используя следующие поля и средства доступа:

 private Map<String, List<String>> environments = new HashMap<String, List<String>>();

@JsonProperty
public Map<String, List<String>> getEnvironments() {
    return environments;
}

@JsonProperty
public void setEnvironments(Map<String, List<String>> environments) {
    this.environments = environments;
}
 

Я тестирую чтение файла Yaml следующим образом:

 inputStream = new FileInputStream("src/test/resources/configuration_test.yml");
config = mapper.readValue(inputStream, MyConfiguration.class);
 

Следующее исключение генерируется с помощью трассировки стека, которая не особенно полезна:

 Caused by: java.lang.IllegalArgumentException: Can not find a deserializer for non-concrete Collection type [collection type; class com.google.common.collect.ImmutableList, contains [simple type, class io.dropwizard.metrics.ReporterFactory]]
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.createCollectionDeserializer(BasicDeserializerFactory.java:814)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:392)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:350)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:263)
... 42 more
 

Есть идеи, как заставить Джексона анализировать значение карты в виде списка?

Ответ №1:

У меня была такая же проблема с расширением класса конфигурации dropwizard. Как упоминалось в CAB, использование Jackson.newObjectMapper вместо new ObjectMapper решило проблему. Теперь мой тест выглядит так:

 ObjectMapper mapper = Jackson.newObjectMapper(new YAMLFactory());

MyConfiguration myConfig = mapper.readValue(fixture("fixtures/configuration.yml"), MyConfiguration.class);

// Asserts
 

PS: я использую io.dropwizard.testing.FixtureHelpers.fixture для извлечения файла YAML.

Комментарии:

1. Я не могу сделать то же самое, поскольку newObjectMapper() не принимает никаких аргументов.

2. Какую версию dropwizard вы используете?

3. Версия Dropwizard 0.7.1

4. Я использую 0.8, Jackson класс является частью dropwizard io.dropwizard.jackson . Вы можете либо обновить свою версию DW, либо использовать ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); .

Ответ №2:

Вам необходимо правильно настроить свой ObjectMapper. В dropwizard есть Jackson.newObjectMapper()

Ответ №3:

На самом деле это было связано с тем, что мой класс привязки расширялся из класса конфигурации DropWizard. Синтаксический анализ Yaml, упомянутый в проблеме, работал нормально при использовании класса привязки, который не был расширен из класса конфигурации DropWizard.

Стоит отметить, что исключение возникало только при запуске в тесте JUnit (TDD, конечно), а не при запуске приложения DropWizard. Исключение не возникло, когда файл Yaml был прочитан во время обычного запуска приложения.