欢迎光临
我们一直在努力

如何使用Java基于SnakeYAML实现YAML文件的解析与序列化?

JAVA基于SnakeYAML实现解析与序列化YAML

如何使用Java基于SnakeYAML实现YAML文件的解析与序列化?

概述

本文将详细介绍如何使用SnakeYAML库在Java中进行YAML文档的解析和序列化,我们将从项目设置开始,逐步讲解如何加载、解析、自定义类型、处理隐式类型以及嵌套对象等。

项目设置

要在项目中使用SnakeYAML,需要添加Maven依赖项(可在此处找到最新版本):

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

入口点

该YAML类是API的入口点:

Yaml yaml = new Yaml();

由于实现不是线程安全的,因此不同的线程必须具有自己的Yaml实例。

加载YAML文档

SnakeYAML支持从String或InputStream加载文档,我们从定义一个简单的YAML文档开始,然后将文件命名为customer.yaml

firstName: "John"
lastName: "Doe"
age: 20

4.1 基本用法

我们将使用Yaml类来解析上述YAML文档:

Yaml yaml = new Yaml();
InputStream inputStream = this.getClass()
  .getClassLoader()
  .getResourceAsStream("customer.yaml");
Map<String, Object> obj = yaml.load(inputStream);
System.out.println(obj);

上面的代码生成以下输出:

{firstName=John, lastName=Doe, age=20}

默认情况下,load()方法返回一个Map对象,查询Map对象时,我们需要事先知道属性键的名称,否则容易出错,更好的办法是自定义类型。

4.2 自定义类型解析

如何使用Java基于SnakeYAML实现YAML文件的解析与序列化?

SnakeYAML提供了一种将文档解析为自定义类型的方法,让我们定义一个Customer类,然后尝试再次加载该文档:

public class Customer {
    private String firstName;
    private String lastName;
    private int age;
    // getters and setters
}

现在我么来加载:

Yaml yaml = new Yaml();
InputStream inputStream = this.getClass()
 .getClassLoader()
 .getResourceAsStream("customer.yaml");
Customer customer = yaml.load(inputStream);

还有一种方法是使用Constructor:

Yaml yaml = new Yaml(new Constructor(Customer.class));

4.3 隐式类型

如果没有为给定属性定义类型,则库会自动将值转换为隐式type。

1.0 >Float

42 >Integer

20090330 >Date

让我们使用一个TestCase来测试这种隐式类型转换:

@Test
public void whenLoadYAML_thenLoadCorrectImplicitTypes() {
   Yaml yaml = new Yaml();
   Map<Object, Object> document = yaml.load("3.0: 20180722");
   assertNotNull(document);
   assertEquals(1, document.size());
   assertTrue(document.containsKey(3.0d));   
}

4.4 嵌套对象

如何使用Java基于SnakeYAML实现YAML文件的解析与序列化?

SnakeYAML 支持嵌套的复杂类型,让我们向“ customer.yaml”添加“联系方式”和“地址”详细信息,并将新文件另存为customer_with_contact_details_and_address.yaml

firstName: "John"
lastName: "Doe"
age: 31
contactDetails:
    type: "mobile"
     number: 123456789
    type: "landline"
     number: 456786868
homeAddress:
   line: "Xyz, DEF Street"
   city: "City Y"
   state: "State Y"
   zip: 345657

我们来更新java类:

public class Customer {
    private String firstName;
    private String lastName;
    private int age;
    private List<Contact> contactDetails;
    private Address homeAddress;    
    // getters and setters
}
public class Contact {
    private String type;
    private int number;
    // getters and setters
}
public class Address {
    private String line;
    private String city;
    private String state;
    private Integer zip;
    // getters and setters
}

我们来测试下Yaml的load():

@Test
public void whenLoadYAMLDocumentWithTopLevelClass_thenLoadCorrectJavaObjectWithNestedObjects() {
  Yaml yaml = new Yaml(new Constructor(Customer.class));
  InputStream inputStream = this.getClass()
      .getClassLoader()
      .getResourceAsStream("yaml/customer_with_contact_details_and_address.yaml");
  Customer customer = yaml.load(inputStream);
  assertNotNull(customer);
  assertEquals("John", customer.getFirstName());
}

相关问题与解答栏目

问题1: SnakeYAML如何处理线程安全问题?

答案: SnakeYAML的实现不是线程安全的,因此每个线程应创建自己的Yaml实例,这可以通过在需要的地方创建局部变量来实现。

问题2: 如果YAML文件中的属性没有明确指定类型,SnakeYAML会如何处理?

答案: 如果YAML文件中的属性没有明确指定类型,SnakeYAML会根据内容自动推断类型,字符串会被解析为String,整数会被解析为Integer,浮点数会被解析为Float等。

小伙伴们,上文介绍了“JAVA基于SnakeYAML实现解析与序列化YAML”的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。

赞(0)
版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:《如何使用Java基于SnakeYAML实现YAML文件的解析与序列化?》
文章链接:https://yuyunkj.com/article/9518.html
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。

评论 抢沙发