Yaml | 从0开始的实践操作(Java)

6,448 阅读3分钟

IDEA中创建yaml文件

参考来源:解决idea不支持SpringBoot yml文件

Idea默认不识别yml(yaml)文件且对yml文件没有提示,因此需要进行一些配置。

  • 菜单栏:Settings -> Plugins -> YAML。Idea默认是有YAML插件。
  • 添加两个插件:
    • YAML/Ansible support
    • SnakeYAML plugin

两个插件添加完毕之后,Idea就能识别yml文件且有提示。如果需要将yml文件添加为SpringBoot的系统文件,需要参考SpringBoot-添加yml为系统文件

spring boot项目中同时存在application.properties和application.yml文件时,两个文件都有效,但是application.properties的优先级会比application.yml高。

写入和读取yaml文件

写入yaml文件

对于SpringBoot项目,创建的yml文件一般放在 resources 文件下,如E:\Code\projectname\src\main\resources\conf.yml。

按照yaml文件的语法写入数据:

http:
  request:
    headers:
      tabValue:
        httpRequestHeaders
      type:
        plaintext
    body:
      tabValue:
        httpRequestBody
      type:
        plaintext

注:yaml文件只允许使用 空格 控制层级,不允许使用tab。

读取yaml文件

参考来源:Java读取resource文件/路径的几种方式

通常使用这两种方式:

import org.yaml.snakeyaml.Yaml;
Yaml yaml = new Yaml();
confName = "conf.yml";

//获取文件路径,如 E:\Code\projectname\src\main\resources\conf.yml
String fileName = this.getClass().getClassLoader().getResource(confName).getPath();
yaml.load(fileName)

//直接读取yaml文件为InputStream
//注:InputStream需要用try{}catch{}处理异常,这里省略了
InputStream input = this.getClass().getClassLoader().getResourceAsStream(confName);
yaml.load(input)

使用SnakeYaml操作yaml文件

在SnakeYaml官网上获得最新的maven依赖项

<!--引入snakeyaml包,处理yaml配置文件-->
<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
    <version>1.26</version>
</dependency>

SnakeYaml的具体使用请参考:

主要的两个方法:

  • load():将yaml文件加载为对象。默认情况下。load方法返回一个 Map对象。SnakeYAML支持从String或InputStream加载文档。
  • dump():将object或者pojo序列化为yml。

【注意】以下这两种yaml数据格式均可转换为json。

(1)默认的yaml数据格式,一般为手写。

http:
  request:
    headers:
      tabValue:
        httpRequestHeaders
      type:
        plaintext
    body:
      tabValue:
        httpRequestBody
      type:
        plaintext

(2)使用yaml.dump()写为yaml文件时会产生如下的数据格式。

http:
  request:
    headers: {tabValue: httpRequestHeaders, type: plaintext}
    body: {tabValue: httpRequestBody, type: plaintext}

代码实践

  • 读取SpringBoot项目下的 resources 文件夹下的yml文件,写入数据库再从数据库读取
  • 直接读取yml文件
  • 将读取的yml文件数据转为json

(1)读取SpringBoot项目下的 resources 文件夹下的yml文件,写入数据库再从数据库读取

import org.yaml.snakeyaml.Yaml;

/**
 * 将yaml配置文件的内容加载为yaml写入数据库
 * */
public void writeConf(String confName) {
    InputStream input = null;
    try {
        input = this.getClass().getClassLoader().getResourceAsStream(confName);
    } catch (Exception e){
        //
    }

    //加载配置文件内容为yaml
    Yaml yaml = new Yaml();
    String contentYaml = yaml.dump(yaml.load(input));

    Conf conf = new Conf();
    conf.setConfName(hisnifferConf);
    conf.setContent(contentYaml);
    confMapper.insert(conf);
}

/**
 * 从数据库读取yml配置文件
 * @param confName 配置文件名称
 * @return yaml类型的字符串
 * 注:配置文件名唯一,返回的结果也是唯一的
 * */
public String readConfFromDb(String confName){
    ConfExample example = new ConfExample();
    ConfExample.Criteria criteria = example.createCriteria();
    if (!StringUtils.isEmpty(confName) ){
        criteria.andConfNameEqualTo(confName);
    }
    List<Conf> list = confMapper.selectByExampleWithBLOBs(example);
    if (ListUtil.isEmpty(list)) {
        throw new BaseRuntimeException(ResultCode.PARAM_ILLEGAL.modifyMessage("配置文件找不到:confName=" + confName));
    }
    return list.get(0).getContent();
}

(2)直接读取yml文件

/**
 * 直接读取yml配置文件
 * @param confName 配置文件名称 (从全局配置环境中读取)
 * @return yaml的InputStream
 * */
public InputStream readConfFromYaml(String confName){
    InputStream input = null;
    try {
        input = this.getClass().getClassLoader().getResourceAsStream(confName);
    } catch (Exception e){
        //
    }
    return input;
}

(3)将读取的yml文件数据转为json

注:只要yaml.load()接收的变量为一个对象,那么加载的数据会自动按照这个对象排列数据。

confName = "conf.yml";

Map<String,Object> mapDb = (Map<String, Object>) yaml.load(readConfFromDb(confName));
Map<String,Object> mapYaml = (Map<String, Object>) yaml.load(readConfFromYaml(confName));

返回的json数据格式为:

"http":{
  "request":{
    "headers":{
      "tabValue":"httpRequestHeaders",
      "type":"plaintext"
    },
    "body":{
      "tabValue":"httpRequestBody",
      "type":"plaintext"
    }
  }
}