Search code examples
javajacksonjackson-dataformat-yaml

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

  • 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());