Slevin
Slevin

Reputation: 1294

How to convert a Properties Object to Custom Object using Jackson?

In a Spring Boot application, Spring Boot is used to build a Properties object from a YAML file as follows:

YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
yamlFactory.setResources(new DefaultResourceLoader().getResource("application.yml"));
Properties properties = yamlFactory.getObject();

The reason why Spring Boot's own parser is used is that it not only reads YAML-compliant settings, but also dot-notated properties like e.g:

artist.elvis.name: "Elvis"
artist.elvis.message: "Aloha from Hawaii"

Now that the Properties object is built, I want to map it into an object like the following for example:

@JsonIgnoreProperties(ignoreUnknown = true)
private record Artist(Elvis elvis) {

    private record Elvis(String name, String message) { }
}

My question is:

How can this be done with Jackson? Or is there another/better solution for this?


Many thanks for any help

Upvotes: 1

Views: 781

Answers (2)

gneginskiy
gneginskiy

Reputation: 91

I saw functionality like that in Ratpack framework. e.g.:

        var propsFileUrl =
                Thread.currentThread()
                        .getContextClassLoader()
                        .getResource("application.properties");

        ApplicationProperties applicationProperties =
                ConfigData.builder()
                        .props(propsFileUrl)
                        .build()
                        .get(ApplicationProperties.class);

under the hood it is indeed done by using jackson's object mapper, but the logic is not as trivial to post it here.

here's the library:

https://mvnrepository.com/artifact/io.ratpack/ratpack-core/2.0.0-rc-1

Upvotes: 1

mahfuj asif
mahfuj asif

Reputation: 1979

application.yml is the default yml file, so no custom configuration is required. Value annotation should be able to read the properties.

@Value("${artist.elvis.name}")
private String name;

Next part I am not sure about your requirements, but hope this is what you are looking for.

To bind to this object 'constructor' can be a good option. Class for elvis

@Bean
public class Elvis {
  private String name;
  private String message;

  public Elvis(@Value("${artist.elvis.name"}) final String name, @Value("${artist.elvis.message"}) final String message) {
     this.name=name;
     this.message=message
  }

  // getter setter for name and message
}

Now Autowire the created bean to Artist bean

@Bean("artists")
public class Artists {
  @Autowired
  private Elvis elvis
  
  pubic Elvis getElvis() {
    return elvis;
  }
}

Upvotes: 0

Related Questions