In the Java world, configuration is left to Properties, and this module dates back to the old JDK1.0.

“Oh my God, this is 20 years ago and I still use Properties…”

However, the main character of this article is not Properties, but Yaml.

This is the darling of the new era of microservices architecture, and Yaml is a bit of a bandit compared to Properties. Properties profiles can be found in most previous projects, including for business property configuration, machine-machine interface interaction, internationalization, and so on. And in a few cases, there are some “hybrid” practices, such as:

  • Use Xml to represent some templates

  • Use a JSON-formatted string

  • Streaking text format, application self-parsing…

Mixed configuration often occurs in projects with a “bad taste” because code is stale, stale, and so on, and it is difficult to form a unified approach. However, apart from the simple configuration method of the Properties property file, the other methods are nothing more than to adapt to the complex and diversified requirements of configuration.

Yaml, then, is designed for this scenario, and much of the official SpringBoot documentation uses the configuration format of the Yaml syntax. Here is an introduction to Yaml and how it is used.

What is Yaml

Definition from encyclopedia:

“Yaml is a readable, easy-to-use data serialization format first published by Clark Evans in 2001.”

You can see that Yaml is not a very new thing, but not many people in the past. In addition, Yaml is supported by a variety of programming languages and frameworks with high versatility. In the Java architecture, common microservices frameworks support or even recommend Yaml as the preferred configuration language.

What is special about Yaml itself? Take a look at the following example:


     

    environments:

    dev:

    url: https://dev.example.com

    name: Developer Setup

    prod:

    url: https://another.example.com

    name: My Cool App

Copy the code

This syntax is equivalent to Properties:


     

    environments.dev.url=https://dev.example.com

    environments.dev.name=Developer Setup

    environments.prod.url=https://another.example.com

    environments.prod.name=My Cool App

Copy the code

As you can see, YAML is more structured and better suited for expressing an object. Syntactically it has the following characteristics:

  • Case sensitivity

  • The use of space indentation for hierarchy, rather than the Tab key, is mainly due to the need to align text on different platforms

  • The number of Spaces indented does not matter, as long as elements of the same rank are aligned to the left

  • Use a # as a comment line

  • Use a hyphen (-) to describe array elements

Comparing the Properties

Properties is a good way to implement key-value configuration, including as a way to configure some international content. However, it is difficult for Properties to show multi-level nested relationships, and Yaml can make up for this shortcoming.

Compared to Json

Yaml and Json are both structured expression languages, but Json was designed to be easy to use and easy to transfer. Yaml, on the other hand, focuses on readability (and more on appearance), almost as a “superset” of Json, a more readable (and prettier) structured format.

In addition, Json is easier to generate and parse, and is suitable for transfer and interaction in a variety of cross-language, distributed environments. Yaml, meanwhile, is generally used for more configurations.

The definition of Yaml can be accessed at the following address:

http://www.yaml.org/spec/1.2/spec.html

Yaml syntax

Yaml is very compact and defines only three elements:

  • Object: a collection of key-value pairs corresponding to a Java HashMap

  • Array: AN ordered set of values, corresponding to a List in Java

  • 1. A single, nondivisible value, such as 3, “Jackson”.

How objects are represented

Properties of an object, nesting relationships are represented by indented space alignment as follows:


     

    article:

    Title: A man's confession

    author:

    Name: Chen ling

    gender: female

Copy the code

How to represent an array

The elements of the array are represented by a hyphen (-), as follows:


     

    article:

    Title: A man's confession

    tags:

    Biography -

    - social

    - people

Copy the code

The basic unit that makes up the contents of an object or array is a single value. Yaml supports seven types of single values:

type sample
string Bob
Boolean value true
The integer 199
Floating point Numbers 19.91
Null ~
time The 2001-12-14 T22:14:09. 10 + 08:00
The date of 2019-01-09

Among them, the date, time, using the ISO 8601 international standard format, about the definition of it can refer to: https://www.w3.org/TR/NOTE-datetime

Typically, a single value ends on a line. However, if you encounter a multi-line string, you can use some special characters, such as:


     

    text: |

    Hello

    World

Copy the code

The corresponding results are:


     

    { text: 'Hello\nWorld\n' }

Copy the code

We can use + to preserve the end of the string and – to remove the end of the string:


     

    text1: |+

    Hello

    text2: |-

    Hello

Copy the code

The corresponding results are:


     

    { text1: 'Hello\n\n\n', text2: 'Hello' }

Copy the code

In addition, Yaml supports advanced uses such as references, functions, and regular expressions, which are rarely used on projects.

3. Operate Yaml

The common component currently used to manipulate Yaml is Snake Yaml, which supports the standard Yaml 1.1 version.

The Official SpringBoot documentation also describes how to integrate the framework at the following address: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-loading-yaml

A sample of integrating SnakeYaml into a project is provided below.

A. Introduce frameworks

In Maven’s POM.xml file add:


     

    <dependency>

    <groupId>org.yaml</groupId>

    <artifactId>snakeyaml</artifactId>

    < version > 1.21 < / version >

    </dependency>

Copy the code

B. Code snippets

Implement loading the configuration file

The following code loads the YAML configuration from the classpath config.yml file:


     

    InputStream inputStream = YamlUtil.class.getClassLoader()

    .getResourceAsStream("config.yml");

    Yaml yaml = new Yaml();

    Map<String, Object> objectMap = yaml.load(inputStream);

    System.out.println(objectMap.get("path"));

Copy the code

Implementing object conversion

Define the following Pojo objects:


     

    public static class A{

    private String name = "hello";

    private List<B> bs = new ArrayList<B>();

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name = name;

    }

    public List<B> getBs() {

    return bs;

    }

    public void setBs(List<B> bs) {

    this.bs = bs;

    }

    }

    public static class B{

    private String id = UUID.randomUUID().toString();

    public String getId() {

    return id;

    }

    public void setId(String id) {

    this.id = id;

    }

    }

Copy the code

Code to output an object in Yaml format via SnakeYaml:


     

    A a = new A();

    a.getBs().add(new B());

    a.getBs().add(new B());

    Yaml yaml = new Yaml();

    String aString = yaml.dumpAsMap(a);

    System.out.println(aString);

Copy the code

The following output is displayed:


     

    bs:

    - id: b3688f05-ea7e-436b-bc9a-9c5df555c7fd

    - id: 7906224d-8ecc-43b8-bc3b-07985bc18ebd

    name: hello

Copy the code

At this point, if you want to reverse the Yaml text to an A object, you can execute the following code:


     

    A a1 = new Yaml().parseToObject(aString, A.class);

    .

Copy the code

C. Complete case

Finally, we can encapsulate the operations of Yaml documents as a utility class that can be easily integrated into business code.

YamlUtil.java

                            
     

    public class YamlUtil {

    / * *

    Load content from a resource file and parse it into a Map object

    *

    * @param path

    * @return

    * /

    public static Map< String, Object> loadToMap( String path) {

    if (StringUtils.isEmpty(path)) {

    return Collections.emptyMap();

    }

    InputStream inputStream = YamlUtil. class.getClassLoader()

    .getResourceAsStream(path);

    Yaml yaml = new Yaml();

    Map objectMap = yaml.load(inputStream); ,>

    return objectMap;

    }

    / * *

    * Parse strings into Map objects

    *

    * @param content

    * @return

    * /

    public static Map< String, Object> parseToMap( String content) {

    if (StringUtils.isEmpty(content)) {

    return Collections.emptyMap();

    }

    Yaml yaml = new Yaml();

    Map objectMap = yaml.load(content); ,>

    return objectMap;

    }

    / * *

    * Parse a string into a class object

    *

    * @param content

    * @param clazz

    * @param <T>

    * @return

    * /

    public static T parseToObject( String content, Class clazz) {

    if (StringUtils.isEmpty(content) || clazz == null) {

    return null;

    }

    Yaml yaml = new Yaml( new Constructor(clazz));

    T object = yaml.load(content);

    return object;

    }

    / * *

    * Formatting objects

    *

    * @param object

    * @return

    * /

    public static String format( Object object) {

    Yaml yaml = new Yaml();

    return yaml.dumpAsMap( object);

    }

    }

Copy the code

At this point, we are done reading and writing Yaml. Of course, in addition to Snake Yaml, you can also use the popular Jackson component to accomplish similar functions. I won’t go into too much detail here, but you can try it out for yourself.

Reference documentation

Ruan Yifeng -YAML Language Tutorial:

http://www.ruanyifeng.com/blog/2016/07/yaml.html

SnakeYaml Official documentation:

https://bitbucket.org/asomov/snakeyaml/wiki/Documentation

Yaml 1.2 specification:

http://www.yaml.org/spec/1.2/spec.html

SpringBoot-LoadingYaml

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-loading-yaml

Check out the Coder’s SpringBoot tutorial series