使用 SnakeYAML 解析 YAML
1.介绍
如何使用 SnakeYAML 库将 Java 对象序列化为 YAML 文档,或YAML文档转为Java对象
2.依赖
<dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.21</version>
</dependency>
3.入口点
Yaml 类是 API 的入口点:
Yaml yaml = new Yaml();
由于实现不是线程安全的,不同的线程必须有自己的 Yaml 实例。
4.加载 YAML 文档
该库支持从 String 或 InputStream 加载文档。 示例将基于解析 InputStream。
首先定义一个简单的 YAML 文档, customer.yaml:
firstName: "张"
lastName: "三"
age: 20
4.1. 基本用法
使用 Yaml 类解析上面的 YAML 文档:
@Test
public void loadToMap() {Yaml yaml = new Yaml();InputStream inputStream = YamlTest1.class.getClassLoader().getResourceAsStream("yaml/customer.yaml");Map<String, Object> obj = yaml.load(inputStream);System.out.println(obj);
}
输出
{firstName=张, lastName=三, age=20}
默认情况下, load() 方法返回一个 Map 实例。 每次查询 Map 对象都需要提前知道属性键名,而且遍历嵌套属性也不容易。
4.2. 自定义类型
该库还提供了一种将文档作为自定义类加载的方法。 此选项将允许轻松遍历内存中的数据。
定义一个 Customer 类并尝试再次加载文档:
@Data
public class Customer {private String firstName;private String lastName;private int age;
}
YAML 文档被反序列化为已知类型,可以在文档中指定一个显式的全局标签。
新建customer_with_type.yaml文件
!!com.niugang.javabase.yaml.Customer
firstName: "李"
lastName: "四"
age: 20
请注意文档中的第一行,其中包含有关加载类时要使用的类的信息。
@Test
public void loadToObjectType() {Yaml yaml = new Yaml();InputStream inputStream = YamlTest1.class.getClassLoader().getResourceAsStream("yaml/customer_with_type.yaml");Customer customer = yaml.load(inputStream);System.out.println(customer);
}
load() 方法现在返回一个 Customer 类型的实例。 这种方法的缺点是必须将类型指定到YAML文件中。
加载自定义类型的另一种方法是使用 Constructor 类。 通过这种方式,可以为要解析的 YAML 文档指定根类型。 创建一个以 Customer 类型为根类型的 Constructor 实例,并将其传递给 Yaml 实例。
现在加载 customer_no_type.yaml,获得 Customer 对象:
firstName: "李"
lastName: "四"
age: 20
@Test
public void loadToObjectType2() {Yaml yaml = new Yaml(new Constructor(Customer.class));InputStream inputStream = YamlTest1.class.getClassLoader().getResourceAsStream("yaml/customer_no_type.yaml");Customer customer = yaml.load(inputStream);System.out.println(customer);
}
4.3. 隐式类型
如果没有为给定属性定义类型,库会自动将值转换为隐式类型。
例如:
1.0 -> Float
42 -> Integer
2009-03-30 -> Date
@Testpublic void implicitTypes() {Yaml yaml = new Yaml();Map<Object, Object> document = yaml.load("3.0: 2021-08-07");System.out.println(document);//{3.0=Sat Aug 07 08:00:00 CST 2021}}
4.4. 嵌套对象和集合
给定顶级类型,库会自动检测嵌套对象的类型,除非它们是接口或抽象类,并将文档反序列化为相关的嵌套类型。
customer_with_contact_details_and_address.yaml
firstName: "张"
lastName: "三"
age: 31
contactDetails:- type: "mobile"number: 123456789- type: "landline"number: 456786868
homeAddress:line: "16号"city: "西安"state: "长安街"zip: 345657
转化类
@Data
public class CustomerNest {private String firstName;private String lastName;private int age;private List<Contact> contactDetails;private Address homeAddress;
}
@Data
public class Address {private String line;private String city;private String state;private Integer zip;
}
@Data
public class Contact {private String type;private int number;
}
@Test
public void nestedObjects() {Yaml yaml = new Yaml(new Constructor(CustomerNest.class));InputStream inputStream = YamlTest1.class.getClassLoader().getResourceAsStream("yaml/customer_with_contact_details_and_address.yaml");CustomerNest customer = yaml.load(inputStream);System.out.println(customer);
}
单元测试
@Test
public void nestedObjects() {Yaml yaml = new Yaml(new Constructor(CustomerNest.class));InputStream inputStream = YamlTest.class.getClassLoader().getResourceAsStream("yaml/customer_with_contact_details_and_address.yaml");CustomerNest customer = yaml.load(inputStream);System.out.println(customer);
}
4.5. 类型安全集合
当给定 Java 类的一个或多个属性是类型安全(通用)集合时,指定TypeDescription以便识别正确的参数化类型就很重要。
为了加载此文档,可以为顶级类的给定属性指定*TypeDescription* :
@Test
public void nestedObjects2() {Constructor constructor = new Constructor(CustomerNest.class);TypeDescription customTypeDescription = new TypeDescription(CustomerNest.class);customTypeDescription.addPropertyParameters("contactDetails", Contact.class);constructor.addTypeDescription(customTypeDescription);Yaml yaml = new Yaml(constructor);InputStream inputStream = YamlTest.class.getClassLoader().getResourceAsStream("yaml/customer_with_contact_details_and_address.yaml");CustomerNest customer = yaml.load(inputStream);System.out.println(customer);
}
4.6. 加载多个文档
可能存在这样的情况,在单个文件中有多个 YAML 文档,想要解析所有这些文档。所述YAML类提供了一个LOADALL()方法来完成这种类型的解析。
默认情况下,该方法返回Iterable的实例,其中每个对象的类型为Map<String, Object>。 如果需要自定义类型,那可以使用 上面讨论的Constructor实例。
示例如下:
---
firstName: "张"
lastName: "三"
age: 20
---
firstName: "李"
lastName: "四"
age: 25
单元测试如下:
@Test
public void loadMore() {Yaml yaml = new Yaml(new Constructor(Customer.class));InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("yaml/customer_more.yaml");int count = 0;for (Object object : yaml.loadAll(inputStream)) {count++;System.out.println(object);}System.out.println(count);}
5. 转储 YAML 文件
该库还提供了一种将给定 Java 对象转储到 YAML 文档中的方法。输出可以是字符串或指定的文件/流。
5.1. 基本用法
一个将Map<String, Object>实例转储到 YAML 文档 (String)的简单示例
/*** 写入到字符串流中*/
@Test
public void mapGenerateCorrectYAML() {Map<String, Object> data = new LinkedHashMap<>();data.put("name", "张三");data.put("age", "25");data.put("mobile", new String[] { "15012345678", "18745612378" });Yaml yaml = new Yaml();StringWriter writer = new StringWriter();yaml.dump(data, writer);System.out.println(writer.toString());}
将数据写入yaml文件中
/**
* 写入到文件中
*/
@Test
public void mapGenerateCorrectYAMLFile() throws IOException {Map<String, Object> data = new LinkedHashMap<>();data.put("name", "张三");data.put("age", "25");data.put("mobile", new String[] { "15012345678", "18745612378" });Yaml yaml = new Yaml();FileWriter writer = new FileWriter("map.yaml");yaml.dump(data, writer);System.out.println(writer.toString());}
5.2. 自定义 Java 对象
可以选择将自定义 Java 类型转储到输出流中或文件中
以下单元测试演示,从一个yaml读取java对象,写入另外一个yaml文件中
@Test
public void writerData() {Yaml yamlWrite = new Yaml();Yaml yamlRead = new Yaml(new Constructor(CustomerNest.class));InputStream inputStream = YamlTest.class.getClassLoader().getResourceAsStream("yaml/customer_with_contact_details_and_address.yaml");CustomerNest customer = yamlRead.load(inputStream);try {FileWriter fileWriter = new FileWriter("test.yaml");//写数据yamlWrite.dump(customer, fileWriter);} catch (IOException e) {e.printStackTrace();}}
为了避免输出文件中的标签名,可以使用库提供的 dumpAs()方法,指定输出的标签。
所以在上面的代码中,可以调整以下内容以删除标签:
yaml.dumpAs(customer, Tag.MAP, null);
使用 SnakeYAML 解析 YAML相关推荐
- Java解析yaml文件
Java解析yaml文件 1. 什么是yaml ? 2. 导入maven依赖 3. yaml 案例文件 4. 示例代码 5. 解析结果 1. 什么是yaml ? 参考下方链接 yaml快速入门 2. ...
- 如何在Python中解析YAML文件
如何在Python中解析YAML文件? #1楼 不依赖C标头的最简单,最纯净的方法是PyYaml( 文档 ): #!/usr/bin/env pythonimport yamlwith open(&q ...
- java读取yaml配置文件,snakeyaml读取yaml配置文件
下面上我解析yaml文件的例子: // me.yaml age: 1 name: jiaobuchong params: event: what's up url: http://www.jiaobu ...
- Golang解析yaml格式文件
关注公众号 风色年代(itfantasycc) 300G微服务资料等你拿! 作者:会飞的鲶鱼 链接:Golang解析yaml格式文件 - 简书 來源:简书 简书著作权归作者所有,任何形式的转载都请联系 ...
- go解析yaml文件示例
yaml文件已经成为配置的一种主要格式,因此各种语言都提供了相应的解析类库, 本文就以go语言中常用的yaml解析库 gopkg.in/yaml为例,简单展示一下如何解析yaml文件 具体代码在这里: ...
- Golang 解析Yaml格式
Golang官方并没有提供Yaml解析包,所以需要使用第三方包.可用的第三方包有不少,这里选择的是 gopkg.in/yaml.v2,这个包在github上有不少的star,也的确挺好用.其使用的是A ...
- vue中使用CodeMirror解析yaml语言
vue中使用CodeMirror解析yaml语言 一.CodeMirror插件使用 1.CodeMirror插件安装 二.CodeMirror基本配置 三.CodeMirror具体使用 1.首先创建一 ...
- java snakeyaml_JAVA使用SnakeYAML解析与序列化YAML
1.概述 本文,我们将学习如何使用SnakeYAML库将 YAML文档转换为Java对象,以及JAVA对象如何序列化为YAML文档. 2.项目设置 要在项目中使用SnakeYAML,需要添加Maven ...
- yml java集合_JAVA 使用 SnakeYAML 解析与序列化 YAML
1.概述 本文,我们将学习如何使用SnakeYAML库将 YAML文档转换为Java对象,以及JAVA对象如何序列化为YAML文档. 2.项目设置 要在项目中使用SnakeYAML,需要添加Maven ...
- JAVA使用SnakeYAML解析与序列化YAML
1.概述 本文,我们将学习如何使用SnakeYAML库将 YAML文档转换为Java对象,以及JAVA对象如何序列化为YAML文档. 2.项目设置 要在项目中使用SnakeYAML,需要添加Maven ...
最新文章
- 从零到有的突破:BCH爱好者聚集地BCH.Club公测上线
- 使用python用什么软件-Python读写Excel表格,就是这么简单粗暴又好用
- 让Source Insight完美支持中文注释 (转)
- Lomox0.2.0.1_Plugin_beta
- img文件解包工具_使用tar归档命令,就不怕文件多!
- 设备的阻塞与非阻塞操作
- 二元矩阵峰值搜索_好斗的牛(二元搜索)
- 华为mate40搭载鸿蒙,华为mate40搭载鸿蒙还是EMUI11,答案来了
- 滴滴新增对手!腾讯投资的网约车平台OnTime或将于本月上线
- 学计算机科学与技术会特效吗,女生学计算机科学与技术专业会不会很困难?看完你就明白了!...
- UVA10023 Square root【大数】
- 常用地图经纬度转换,以及遇到的问题和解决方式
- 【数字信号调制】基于matlab 16QAM信号调制解调【含Matlab源码 2050期】
- Linux下的tree的简单使用
- 【小程序】JAVA实现从10~50中随机生成50个数,统计出现的数字及次数,输出出现最多的次数及对应的数字,按数字升序排列。
- 学信认证使用Jetbrains教育授权方式
- 计算机多媒体作业是什么,多媒体计算机技术作业一
- ureport2报错/by zero的解决方法
- 渗透扫描工具Nmap下载、安装和使用
- 超详细的程序员未来职业发展路线