Yaml如何理解

发布时间:2022-01-07 21:47:22 作者:柒染
来源:亿速云 阅读:133

Yaml如何理解,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

在Java 的世界里,配置的事情都交给了 Properties,要追溯起来这个模块还是从古老的JDK1.0 就开始了的。

"天哪,这可是20年前的东西了,我居然还在用 Properties.."

然而,本文的主角并不是Properties,而是Yaml。这是新时代里微服务架构上的宠儿,和 Properties 相比起来,Yaml 显得有些弄潮儿。

以往的大多数项目里,我们都可以发现 Properties配置文件的踪迹,这包括用作业务属性配置的、机机接×××互的、国际化的等等用途。
而少量的一些情况下,也存在一些"混合式"的做法,比如:

混杂的配置方式往往出现在一些充满"坏味道"的项目里头,因为代码陈旧、斯人已矣 等原因,很难形成统一的方式。
然而,除开 Properties 属性文件这种简单的配置方式之外,采用其他的方法不外乎都是为了适应配置复杂、多元化的诉求。

那么,Yaml 就是应对这种场景而产生的,在 SpringBoot 的官方文档中,有不少篇幅是 使用了 Yaml 语法的配置格式。
下面介绍一下 Yaml 以及它是如何使用的。

一、什么是 Yaml

来自百科的定义
"Yaml 是一个可读性高,易用的数据序列化格式,由 Clark Evans 在2001年首次发表。"
可见 Yaml 并不是一个很新的东西,只是在以前接触的人不多罢了。此外,Yaml也被各种编程语言及框架所支持, 通用性很高。
在Java体系中,一般的微服务框架都支持甚至优先推荐使用 Yaml 作为首选的配置语言。

而 Yaml 本身具有什么特点?  看看下面的一个实例:

environments:
    dev:
        url: https://dev.example.com
  name: Developer Setup
    prod:
        url: https://another.example.com
        name: My Cool App

这段语法等价的 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

可见, yaml 相对来说更加的结构化,更适合用来表达一个对象。
它在语法上有这样的特点:

对比 Properties
Properties 可以很好的实现 Key-Value 的配置,包括作为一些国际化内容的配置方式。
但 Properties 很难表现多层级的嵌套关系,此时如果用 Yaml 可以较好的弥补该短板。

对比 Json
Yaml 与 Json本身没有太多的优劣之分,两者都是结构化的表达式语言,但是Json的设计重点在于简单易用、方便传输的特性;
而 Yaml 则侧重于可读性(更加在乎外观),几乎可以把 Yaml 看做是 Json 的一个"超集",即可读性更高(更漂亮) 的结构化格式。
此外,Json更加便于生成和解析,适合在各种跨语言、分布式的环境中传输和交互;与此同时, Yaml 则一般只是用作的配置较多。

关于 Yaml 的定义可以访问下面的地址:
http://www.yaml.org/spec/1.2/spec.html

二、Yaml 的语法

Yaml 是非常简单的, 它所定义的元素只有三个:

对象如何表示
一个对象的属性、嵌套关系通过空格缩进对齐来表示,如下:

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

数组如何表示
数组的元素通过连接符(-)来表示,如下:

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

构成对象、数组内容的基本单元是单值,Yaml支持的单个值的类型有七种,如下:

类型范例
字符串Bob
布尔值true
整数199
浮点数19.91
Null~
时间2001-12-14T22:14:09.10+08:00
日期2019-01-09

其中,日期、时间使用的是 ISO 8601 国际标准格式,关于它的定义可以参考:
https://www.w3.org/TR/NOTE-datetime

一般情况下单个值会在一行内结束。但如果遇到多行的字符串,可以使用一些特殊字符表示,
比如:

text: |
  Hello
  World

对应的结果为:

{ text: 'Hello\nWorld\n' }

可以用+表示保留字符串末尾的换行,-表示删除字符串末尾的换行:

text1: |+
  Hello

text2: |-
  Hello

对应的结果为:

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

除此之外,Yaml 还可以支持引用、函数、正则表达式等高级用法,但项目上一般很少用到。

三、操作 Yaml

Yaml如何理解

目前用来操作 Yaml 的常用组件是 Snake Yaml,这个库支持标准的 Yaml 1.1 版本

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 的读写。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

推荐阅读:
  1. kubectl && YAML,深入理解pod对象(下)
  2. yaml是什么?

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

yaml

上一篇:UIChatBox模块示例分析

下一篇:etcd协调服务、raft协议、GRPC协议的原理是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》