java操作yaml文件

前言

YAML(YAML Ain't Markup Language),也可以叫做YML,是一种人性化的数据序列化的语言,类似于XML,JSON。SpringBoot的配置文件就支持yaml文件。官网

语法

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时不允许使用Tab键,只允许使用空格。
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  • #表示注释,从这个字符一直到行尾,都会被解析器忽略。

yaml有三种数据结构

对象

写在一行

address: {province: 山东, city: 济南}

写在多行

address:
  province: 山东
  city: 济南

数组

写在一行

hobbyList: [游泳, 跑步]

写在多行

hobbyList:
  - 游泳
  - 跑步

纯量

  • 字符串 默认不用加引号,包含空格或特殊字符必须加引号,单引号或双引号都可以
userId: S123
username: "lisi"
password: '123456'
province: 山东
city: "济南 : ss"
  • 布尔值
success: true
  • 整数
age: 13
  • 浮点数
weight: 75.5
  • Null
gender: ~
  • 时间
    时间使用ISO8601标准 ISO8601
createDate: 2001-12-14T21:59:43.10+05     

使用snakeyaml将yaml文件解析成javabean

添加maven依赖

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

yaml文件,既可以.yaml结尾,也可以.yml结尾,支持两种方式的扩展名。

userId: 1
username: lisi
password: 123456
address: {province: 山东, city: 济南}
hobbyList: [游泳, 跑步]

userId: 1
username: "lisi"
password: '123456'
address:
  province: 山东
  city: "济南 : ss"
hobbyList:
  - 游泳
  - 跑步
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.List;
import java.util.Objects;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.yaml.snakeyaml.Yaml;

public class Client {

  public static void main(String[] args) {
    InputStream resource = Client.class.getClassLoader().getResourceAsStream("User.yaml");
    if (Objects.nonNull(resource)) {
      Yaml yaml = new Yaml();
      User user = yaml.loadAs(resource, User.class);
      System.out.println(user.getClass());
      System.out.println(user);
    }
  }

  @Setter
  @Getter
  @ToString
  @AllArgsConstructor
  @NoArgsConstructor
  public static class User {

    private String userId;
    private String username;
    private String password;
    private Timestamp createDate;
    private Address address;
    private List<String> hobbyList;
  }

  @Setter
  @Getter
  @ToString
  @AllArgsConstructor
  @NoArgsConstructor
  public static class Address {

    private String province;
    private String city;
  }
}

一键转换,还是很方便的。

使用snakeyaml将单一yaml文件解析成多个对象

userId: 1
username: "lisi"
password: '123456'
address:
  province: 山东
  city: "济南 : ss"
hobbyList:
  - 游泳
  - 跑步
---
userId: 2
username: "lisi2"
password: '123456'
address:
  province: 河南
  city: "郑州 : ss"
hobbyList:
  - 下棋
  - 画画

...
  1. 在单一文件中,可用连续三个连字号(---)区分多个文件。
  2. 另外,还有选择性的连续三个点号( ... )用来表示文件结尾。
import org.yaml.snakeyaml.Yaml;
import java.io.InputStream;
import java.util.Objects;

public class TestYaml {
    public static void main(String[] args) {
        InputStream resource = TestYaml.class.getClassLoader().getResourceAsStream("User.yaml");
        if (Objects.nonNull(resource)) {
            Yaml yaml = new Yaml();
            Iterable<Object> objects = yaml.loadAll(resource);
            for (Object object : objects) {
                System.out.println(object);
            }
        }
    }
}

输出结果为

{userId=1, username=lisi, password=123456, address={province=山东, city=济南 : ss}, hobbyList=[游泳, 跑步]}
{userId=2, username=lisi2, password=123456, address={province=河南, city=郑州 : ss}, hobbyList=[下棋, 画画]}

使用snakeyaml根据javabean生成yaml文件

import java.util.Arrays;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.yaml.snakeyaml.Yaml;

public class Client {

  public static void main(String[] args) {
    User user = new User();
    user.setUserId("1");
    user.setUsername("lisi");
    user.setPassword("123456");
    user.setAddress(new Address("山东", "济南"));
    user.setHobbyList(Arrays.asList("游泳", "跑步"));
    Yaml yaml = new Yaml();
    String userString = yaml.dump(user);
    System.out.println(userString);
    System.out.println(yaml.loadAs(userString, User.class));
  }

  @Setter
  @Getter
  @ToString
  @AllArgsConstructor
  @NoArgsConstructor
  public static class User {

    private String userId;
    private String username;
    private String password;
    private Address address;
    private List<String> hobbyList;
  }

  @Setter
  @Getter
  @ToString
  @AllArgsConstructor
  @NoArgsConstructor
  public static class Address {

    private String province;
    private String city;
  }
}

输出结果为

!!com.imooc.sourcecode.java.yaml.test2.Client$User
address: {city: 济南, province: 山东}
hobbyList: [游泳, 跑步]
password: '123456'
userId: '1'
username: lisi

上面的对象和数组是显示在一行,我们也可以通过自定义序列化显示为多行

import java.util.Arrays;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.Yaml;

public class Client {

  public static void main(String[] args) {
    User user = new User();
    user.setUserId("1");
    user.setUsername("lisi");
    user.setPassword("123456");
    user.setAddress(new Address("山东", "济南"));
    user.setHobbyList(Arrays.asList("游泳", "跑步"));
    //序列化参数
    DumperOptions dumperOptions = new DumperOptions();
    dumperOptions.setDefaultFlowStyle(FlowStyle.BLOCK);
    Yaml yaml = new Yaml(dumperOptions);
    String userString = yaml.dump(user);
    System.out.println(userString);
    System.out.println(yaml.loadAs(userString, User.class));
  }

  @Setter
  @Getter
  @ToString
  @AllArgsConstructor
  @NoArgsConstructor
  public static class User {

    private String userId;
    private String username;
    private String password;
    private Address address;
    private List<String> hobbyList;
  }

  @Setter
  @Getter
  @ToString
  @AllArgsConstructor
  @NoArgsConstructor
  public static class Address {

    private String province;
    private String city;
  }
}

输出结果为

!!com.imooc.sourcecode.java.yaml.test3.Client$User
address:
  city: 济南
  province: 山东
hobbyList:
- 游泳
- 跑步
password: '123456'
userId: '1'
username: lisi

关于snakeyaml的更多用法,请查看 snakeyaml文档

使用jackson将yaml文件解析成javabean

添加依赖

<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-yaml</artifactId>
  <version>2.12.0</version>
</dependency>

jackson-dataformat-yaml是在snakeyaml的基础上又封装了一层。

import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Objects;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

public class Client2 {

  public static void main(String[] args) throws IOException {
    InputStream resource = Client.class.getClassLoader().getResourceAsStream("User.yaml");
    if (Objects.nonNull(resource)) {
      YAMLMapper yamlMapper = new YAMLMapper();
      User user = yamlMapper.readValue(resource, User.class);
      System.out.println(user.getClass());
      System.out.println(user);
    }
  }

  @Setter
  @Getter
  @ToString
  @AllArgsConstructor
  @NoArgsConstructor
  public static class User {

    private String userId;
    private String username;
    private String password;
    private Address address;
    private List<String> hobbyList;
  }

  @Setter
  @Getter
  @ToString
  @AllArgsConstructor
  @NoArgsConstructor
  public static class Address {

    private String province;
    private String city;
  }
}

使用jackson根据javabean生成yaml文件

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import java.util.Arrays;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

public class Client {

  public static void main(String[] args) throws JsonProcessingException {
    User user = new User();
    user.setUserId("1");
    user.setUsername("lisi");
    user.setPassword("123456");
    user.setAddress(new Address("山东", "济南"));
    user.setHobbyList(Arrays.asList("游泳", "跑步"));
    YAMLMapper yamlMapper = new YAMLMapper();
    System.out.println(yamlMapper.writeValueAsString(user));
  }

  @Setter
  @Getter
  @ToString
  @AllArgsConstructor
  @NoArgsConstructor
  public static class User {

    private String userId;
    private String username;
    private String password;
    private Address address;
    private List<String> hobbyList;
  }

  @Setter
  @Getter
  @ToString
  @AllArgsConstructor
  @NoArgsConstructor
  public static class Address {

    private String province;
    private String city;
  }
}

输出结果为

---
userId: "1"
username: "lisi"
password: "123456"
address:
  province: "山东"
  city: "济南"
hobbyList:
- "游泳"
- "跑步"

SpringBoot是如何解析yaml文件的

yaml会将字符串解析成对象的格式,spring会将对象扁平化,如

spring:
  application:
    name: test

spring会转换成spring.application.name=test,和properties文件的格式统一。

参考

YAML 语言教程

posted @ 2020-12-31 23:53  strongmore  阅读(13755)  评论(0编辑  收藏  举报