'Deserializing YAML with root name prefix using Jackson

I would like to deserialize a YAML file into a Java object using Jackson and jackson-dataformat-yaml.

The YAML is

company:
  product:
    settings:
      property: value

The target class is

@Getter @Setter
public class TargetObject {
  private Map<String, String> settings;
}

The code for deserializing is

  TargetObject config =
  new ObjectMapper(new YAMLFactory())
      .readerFor(TargetObject.class)
      .withRootName("company.product")
      .readValue(yamlResource.getInputStream());

I get following exception when executing this code:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Root name ('company') does not match expected ('company.product') for type `a.b.c.TargetObject`

Without the second nesting "product" everything works. Is there any possibility to solve this issue without touching the YAML? I've read about escaping dots as YAML keys like "[company.product]", but sadly that is not an option in my use case.

Regards, Rokko



Solution 1:[1]

You are very close to the solution, the problem stands in the fact you are using the wrong ObjectReader#withRootName method in your code:

TargetObject config =
  new ObjectMapper(new YAMLFactory())
      .readerFor(TargetObject.class)
      .withRootName("company.product") //<-- here the error
      .readValue(yamlResource.getInputStream());

Instead you have to use the ObjectReader#at method to select the yaml part you are interested with the appropriate "/company/product" path to obtain the expected result:

TargetObject config = 
  new ObjectMapper(new YAMLFactory())
      .readerFor(TargetObject.class)
      .at("/company/product") //<--here the new method
      .readValue(yamlResource.getInputStream());

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1