Parsing YAML files using SnakeYAML

Technology: YAML is one of the formats to provide configuration files for any type of language. Previously we used to write properties files for configuration, but if the text repeated and it is very tedious construct the hierarchy keys.

YAML is a Human-friendly data serialization standard for, all major programming languages, most languages now support YAML file formats.

YAML is a superset version of JSON file format, and it is a very convenient format for specifying the hierarchical configuration properties.

SnakeYAML is one of the libraries, most used in the Java-based App Development, spring boot also uses the same for processing YAML files internally.

YAML specifications:

  • YAML is easy to read by humans
  • YAML files will be portable across all programming languages.
  • YAML is easy to use and implement.
  • YAML is very extensible and expressive.
  • YAML has a specific format to support tools.

We will understand how to write yaml files and compare with a properties file format.

Suppose we have below configuration data if we are used properties file format it will like below:

spring.datasource.url =jdbc:mysql://localhost:3306/test
spring.datasource.username =sa
spring.datasource.username=password
spring.jpa.show-sql=true
server.port=8081

If we see spring and data source words are a repeat and it is hard to visualize the hierarchy structure also if we write the same in the yaml file, the structure will look like below:

spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: sa
password: password
jpa:
show-sql: true
server:
port: 8081

Here we can easily visualize the configuration data hierarchy and will be used as the delimiter for line and space data.

SnakeYAML dependency:

Let’s create sample maven project and add the below maven dependency for snakeYAML.

org.yaml
snakeyaml
1.23

Loading yaml file into library:

Library provides support for loading the content from the string, inputstream, and reader classes.

For now, we will use the inputstream to load the file to the library and parse it.

Yaml is the class for the entry point of the library since the yaml class is not a singleton, then different threads will contain their yaml class instance.

Suppose below is the YAML stored in an application.yml file.

firstName: sravan
lastName: kumar
age: 28
Now let’s create inputstream for application.yml file.
InputStream stream = YAMLExample.class.getClassLoader().getResourceAsStream("application.yml");

Where YAMLExample is our main class.

yaml.load(stream) method will load the inputstream and return the object type, we can cast to either Map, custom object.

Suppose if we are using Map as the return type, then

Map<String,Object> yamlData = yaml.load(stream);
System.out.println(yamlData.get("firstName"));

The output will be

sravan
now let`s create new custom object with firstName, lastName, and age fields.

public class Person {
private String firstName;
private String lastName;
private int age;

// setters and getters
@Override
public String toString() {
return "firstName "+firstName+" lastName "+lastName+" age "+age;
}
}
And update the application.yml with below content.
!!org.sample.Person
firstName: sravan
lastName: kumar
age: 28

Where first line is the class name to which we want to cast the load method output.

Person person = yaml.load(stream);

System.out.println(person);

Replace the above lines with previous load method, then output will be

firstName sravan lastName kumar age 28

The drawback of this approach is, to specify the return type in yml file, it should be exported as library/jar file wherever we used.

The snakeYAML library provides another type of the YAML constructor for creating the YAML object.

Yaml yaml = new Yaml(new Constructor(Person.class));

And remove first line of yml file where we specified the class name.

If we execute the same, then we will get the same output as in previous case.

Casting to Nested Objects and Collections:

Update yml with below content:

firstName: sravan
lastName: kumar
age: 28
contactDetails:
- type: mobile
number: 1234567890
- type: landline
number: 9876543210

“-” means collection of object.

contactDetails will contain the collection of type and number fields.

Let`s create the object which contain type and number fields and add a collection of this type with variable conatctDetails in Person class.

public class Contact {
private String type;
private String number;

// setters and getters
@Override
public String toString() {
return "type "+type+" number "+number;
}
}

And updated person class will be:

public class Person {
private String firstName;
private String lastName;
private int age;
private List contactDetails;

// getters and setters
@Override
public String toString() {
return "firstName "+firstName+" lastName "+lastName+" age "+age +" contacts "+contactDetails;
}
}

If we execute the same the output will look like below:

firstName sravan lastName kumar age 28 contacts [type mobile number 1234567890, type landline number 9876543210]

Conclusion: YAML is one of the file format used for providing the configuration data, SnakeYAML is one of the libraries to parse the YML files.

Download the sample code at https://github.com/sravan4rmhyd/snakeYAML.git

One thought on “Parsing YAML files using SnakeYAML

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s