Y service - do you really know Yaml

In the Java world, things are handed over to Configuration Properties, retroactive up to this module or from the old JDK1.0 started in.

"My God, this is something 20 years ago, I actually still use Properties .."

However, the protagonist of this article is not Properties, but Yaml. This is a new era of service on the micro-architecture darling, and Properties In comparison, Yaml a bit of beach-goers.
Most projects in the past, we can find traces Properties profiles, which include service attributes used to configure, machine-machine interface interaction, international, etc. use.
And a small amount of some cases, there are some "hybrid" approach, such as:

  • Xml use to represent some templates
  • A formatted string Json
  • Streaking text format, application self-analytical
    ...

Mixed configurations are often filled in some of the "bad taste" item inside, because the code is old, he died passed away and other reasons, it is difficult to form a unified way.
However, in addition to open Properties properties file such a simple configuration, the use of other methods are nothing more than complex configuration in order to meet diversified demands.

So, Yaml deal with this scenario is produced, in official documents SpringBoot, there are a lot of space is to use a syntax Yaml configuration format.
Here are some Yaml and how it is used.

First, what is Yaml

The definition from Wikipedia :
. "Yaml is a highly readable, easy to use data serialization format by Clark Evans was first published in 2001,"
visible Yaml is not a very new thing, but not many people had contact with the nothing more. In addition, Yaml also supported by a variety of programming languages and frameworks, highly versatile.
In the Java system, the general micro-priority services frameworks support even Yaml recommended as the preferred configuration language.

The Yaml itself has what characteristics? 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

This syntax is equivalent 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

Visible, YAML relatively more structured, more suitable for expression in a subject.
It has such features in the syntax:

  • Case Sensitive
  • Use spaces to indent represent hierarchical relationships, abandon using the Tab key, mainly when taking into account the need to align the text to show on different platforms
  • The number of spaces to indent does not matter, as long as the left elements are aligned to the same level
  • Use as a comment line begins with #
  • Use hyphen (-) at the beginning of the array elements is described

Contrast the Properties
the Properties can be well implemented Key-Value configurations, including a number of international content is configured.
Properties but difficult to show multi-level nesting relationship, if the case may Yaml better compensate for this short board.

Contrast Json
Yaml and Json itself is not much better or worse, both of which are structured expression language, but Json design focuses on ease of use, convenience features transmission;
and Yaml focuses on readability ( more care about appearance) can take almost Yaml Json seen as a "superset", that is more readable (and more beautiful) structured format.
Further, generation and parsing Json easier for various cross-language, distributed environment and interactive transmission; the same time, it is generally only used YAML configuration more.

About the definition of Yaml's location provides access to the following:
http://www.yaml.org/spec/1.2/spec.html

Two, Yaml syntax

Yaml is very simple, it defines only three elements:

  • Object: a collection of key-value pairs that corresponds to the Java HashMap
  • Array: the set of values ​​in sequence, corresponding to the Java List
  • Single-valued: individual, can not be divided value, such as 3, "Jackson"

How object represents
an object attribute, nesting relationship expressed by aligning indentation spaces, as follows:

article:
    title: 一个人的自白书
    author:
        name: 陈玲
        gender: female

How to represent an array
element of the array through a connector - expressed as follows ():

article:
    title: 一个人的自白书
    tags:
        - 传记
        - 社会
        - 人物

Objects constituting the base unit, the contents of the array is a single value, a single value of the type of support has seven Yaml follows:

Types of example
String Bob
Boolean value true
Integer 199
Float 19.91
Null ~
time 2001-12-14T22:14:09.10+08:00
date 2019-01-09

Wherein, date, time using the international standard ISO 8601 format, on its definition reference may be:
https://www.w3.org/TR/NOTE-datetime

Under normal circumstances a single value will end in a row. However, if a multi-line string encounter, you can use some special characters are represented,
such as:

text: |
  Hello
  World

The results corresponding to:

{ text: 'Hello\nWorld\n' }

You can use + expressed reservations about the end of the string line breaks - means to delete the end of the string line breaks:

text1: |+
  Hello
  

text2: |-
  Hello

The results corresponding to:

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

In addition, Yaml also supports references, functions, regular expressions and other advanced usage, but is rarely used on the project.

Third, the operation Yaml

Common components currently used to operate Yaml is Snake Yaml, the library supports the standard Yaml 1.1 version .

SpringBoot 官方文档也介绍了整合该框架的方式,参考下面的地址:
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-loading-yaml

下面提供 将SnakeYaml 整合到项目的样例。

A. 引入框架

在Maven的pom.xml文件中添加:

<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
    <version>1.21</version>
</dependency>

B. 代码片段

实现加载配置文件

如下面的代码,实现了从类路径config.yml文件中加载 yaml 配置内容:

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"));

实现对象转换

定义如下的Pojo 对象:

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;
    }
}

通过 SnakeYaml 将对象输出为 Yaml 格式的代码:

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

输出结果如下:

bs:
- id: b3688f05-ea7e-436b-bc9a-9c5df555c7fd
- id: 7906224d-8ecc-43b8-bc3b-07985bc18ebd
name: hello

此时如果希望将Yaml 文本反过来转换为 A 对象,可以执行下面的代码:

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

C. 完整案例

最终,我们可以将 Yaml 文档的操作封装为一个工具类,方便在业务代码中集成。

YamlUtil.java

public class YamlUtil {

    /**
     * 从资源文件加载内容,并解析为Map对象
     *
     * @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<String, Object> objectMap = yaml.load(inputStream);
        return objectMap;
    }

    /**
     * 将字符串解析为Map对象
     *
     * @param content
     * @return
     */
    public static Map<String, Object> parseToMap(String content) {
        if (StringUtils.isEmpty(content)) {
            return Collections.emptyMap();
        }

        Yaml yaml = new Yaml();
        Map<String, Object> objectMap = yaml.load(content);
        return objectMap;
    }

    /**
     * 将字符串解析为类对象
     *
     * @param content
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T parseToObject(String content, Class<T> clazz) {
        if (StringUtils.isEmpty(content) || clazz == null) {
            return null;
        }

        Yaml yaml = new Yaml(new Constructor(clazz));
        T object = yaml.load(content);
        return object;
    }

    /**
     * 格式化对象
     *
     * @param object
     * @return
     */
    public static String format(Object object) {
        Yaml yaml = new Yaml();
        return yaml.dumpAsMap(object);
    }

}

至此,我们已经完成了 Yaml 的读写。当然,除了上述的Snake Yaml 之外,还可以使用 流行的 Jackson 组件了进行解析,这里不再过多赘述,有兴趣的朋友可以自行尝试。

参考文档

阮一峰-YAML语言教程:
http://www.ruanyifeng.com/blog/2016/07/yaml.html

SnakeYaml 官方文档:
https://bitbucket.org/asomov/snakeyaml/wiki/Documentation

Yaml 1.2 规范:
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

点击查看美码师的 SpringBoot 补习系列

Guess you like

Origin www.cnblogs.com/littleatp/p/11229151.html