解析带有列表值映射的Yaml时出现Jackson异常



我有一个包含与列表对应的映射项的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

任何想法如何让杰克逊解析Map值作为一个列表?

我在扩展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文件。

您需要正确配置您的ObjectMapper。在dropwizard中,有Jackson.newObjectMapper()

这实际上是由于我的绑定类从DropWizard 'Configuration'类扩展。当使用没有从DropWizard 'Configuration'类扩展的绑定类时,解析问题中提到的Yaml工作正常。

值得注意的是,该异常仅在运行JUnit测试(当然是TDD)时发生,而不是在运行DropWizard应用程序时发生。在正常的应用程序启动期间读取Yaml文件时,没有发生异常。