如何使用SnakeYAML解析和生成YAML文件

YAML是一種輕量級數據交換格式,易於閱讀和編寫,被廣泛用於配置文件、數據序列化、日誌記錄等領域。SnakeYAML是一個用Java編寫的YAML解析器和生成器,在Java開發中常常用來讀取和寫入YAML數據。

一、什麼是SnakeYAML

SnakeYAML是一個用Java編寫的YAML解析器和生成器,具有流式API、對象圖API兩種使用方式。它支持嚴格的YAML 1.1規範和寬鬆的YAML 1.2規範,可以輕鬆地讀取和寫入YAML數據。

使用SnakeYAML可以快速地將Java對象序列化為YAML格式的數據,並將YAML格式的數據反序列化為Java對象,非常適用於配置文件、數據存儲和數據交換等場景。

二、SnakeYAML的基本使用

下面我們通過一個簡單的示例來介紹SnakeYAML的基本使用。

1、添加Maven依賴

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

2、將Java對象序列化為YAML格式的數據

import org.yaml.snakeyaml.Yaml;

public class User {
    private String name;
    private int age;

    // 省略構造方法和getter/setter方法

    public static void main(String[] args) {
        User user = new User("張三", 20);

        Yaml yaml = new Yaml();
        String output = yaml.dump(user);

        System.out.println(output);
    }
}

上面的代碼定義了一個User類,用於存儲用戶的姓名和年齡。通過Yaml類的dump方法可以將一個Java對象序列化為YAML格式的數據。

運行上面的代碼,輸出如下:

!!com.example.User
age: 20
name: 張三

可以看到,SnakeYAML將Java對象序列化為了YAML格式的數據,每個屬性對應一個YAML鍵值對。

3、將YAML格式的數據反序列化為Java對象

import org.yaml.snakeyaml.Yaml;

public class User {
    private String name;
    private int age;

    // 省略構造方法和getter/setter方法

    public static void main(String[] args) {
        String input = "!!com.example.User\nage: 20\nname: 張三";

        Yaml yaml = new Yaml();
        User user = yaml.loadAs(input, User.class);

        System.out.println("姓名:" + user.getName());
        System.out.println("年齡:" + user.getAge());
    }
}

上面的代碼將上一步中生成的YAML格式的數據反序列化為了User對象。

運行上面的代碼,輸出如下:

姓名:張三
年齡:20

可以看到,SnakeYAML將YAML格式的數據反序列化為了一個Java對象。

三、SnakeYAML的高級使用

除了基本的序列化和反序列化功能,SnakeYAML還提供了一些高級功能。

1、Java對象圖的序列化和反序列化

上面的示例中介紹了如何將單個Java對象序列化為YAML格式的數據,也介紹了如何將YAML格式的數據反序列化為單個Java對象。但是,在實際應用中,我們有時需要將整個Java對象圖序列化為YAML格式的數據,或者將YAML格式的數據反序列化為整個Java對象圖。

SnakeYAML提供了以下兩種方式來處理Java對象圖的序列化和反序列化:

  • 流式API:使用Dumper和Loader對數據流進行處理
  • 對象圖API:通過創建JavaBean對象模型的方式處理整個Java對象圖

下面我們分別介紹一下這兩種方式的使用。

使用流式API
  • 將Java對象圖序列化為YAML格式的數據
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class User {
    private String name;
    private int age;
    private List<String> hobbies;
    private Map<String, String> addresses;

    // 省略構造方法和getter/setter方法

    public static void main(String[] args) throws Exception {
        User user1 = new User("張三", 20);
        user1.setHobbies(new ArrayList<>());
        user1.getHobbies().add("籃球");
        user1.getHobbies().add("游泳");
        user1.setAddresses(new HashMap<>());
        user1.getAddresses().put("work", "中國北京");
        user1.getAddresses().put("home", "中國上海");

        User user2 = new User("李四", 30);
        user2.setHobbies(new ArrayList<>());
        user2.getHobbies().add("書法");
        user2.getHobbies().add("繪畫");
        user2.setAddresses(new HashMap<>());
        user2.getAddresses().put("work", "中國廣州");
        user2.getAddresses().put("home", "中國深圳");

        List<User> users = new ArrayList<>();
        users.add(user1);
        users.add(user2);

        DumperOptions options = new DumperOptions();
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        options.setPrettyFlow(true);
        options.setExplicitStart(true);

        Yaml yaml = new Yaml(options);
        FileWriter writer = new FileWriter("users.yml");
        yaml.dump(users, writer);

        writer.close();
    }
}

上面的代碼定義了一個User類,用於存儲用戶的姓名、年齡、愛好和地址。通過流式API將兩個User對象序列化為YAML格式的數據,並將數據寫入文件中。

其中,DumperOptions類用於配置序列化的選項。Yaml類的dump方法可以序列化整個Java對象圖,將Java對象圖轉換為YAML格式的數據。

  • 將YAML格式的數據反序列化為Java對象圖
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;

import java.io.FileInputStream;
import java.util.List;

public class User {
    private String name;
    private int age;
    private List<String> hobbies;
    private Map<String, String> addresses;

    // 省略構造方法和getter/setter方法

    public static void main(String[] args) throws Exception {
        LoaderOptions options = new LoaderOptions();
        options.setAllowDuplicateKeys(false);

        Yaml yaml = new Yaml(options);
        FileInputStream stream = new FileInputStream("users.yml");

        List<User> users = yaml.loadAs(stream, List.class);

        stream.close();

        for (User user : users) {
            System.out.println("姓名:" + user.getName());
            System.out.println("年齡:" + user.getAge());
            System.out.println("愛好:" + user.getHobbies());
            System.out.println("地址:" + user.getAddresses());
        }
    }
}

上面的代碼使用流式API將文件中的YAML格式的數據反序列化為Java對象圖,並輸出反序列化後的User對象。

其中,LoaderOptions類用於配置反序列化選項。Yaml類的loadAs方法可以反序列化整個Java對象圖,將YAML格式的數據轉換為Java對象圖。

使用對象圖API

在對象圖API中,可以通過創建JavaBean對象模型的方式處理整個Java對象圖。

  • 將Java對象圖序列化為YAML格式的數據
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Representer;
import org.yaml.snakeyaml.Yaml;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class User {
    private String name;
    private int age;
    private List<String> hobbies;
    private Map<String, String> addresses;

    // 省略構造方法和getter/setter方法

    public static void main(String[] args) {
        User user1 = new User("張三", 20);
        user1.setHobbies(new ArrayList<>());
        user1.getHobbies().add("籃球");
        user1.getHobbies().add("游泳");
        user1.setAddresses(new HashMap<>());
        user1.getAddresses().put("work", "中國北京");
        user1.getAddresses().put("home", "中國上海");

        User user2 = new User("李四", 30);
        user2.setHobbies(new ArrayList<>());
        user2.getHobbies().add("書法");
        user2.getHobbies().add("繪畫");
        user2.setAddresses(new HashMap<>());
        user2.getAddresses().put("work", "中國廣州");
        user2.getAddresses().put("home", "中國深圳");

        List<User> users = new ArrayList<>();
        users.add(user1);
        users.add(user2);

        Representer representer = new Representer();
        representer.addClassTag(User.class, new Tag("!user"));
        representer.addProperty("name", String.class);
        representer.addProperty("age", int.class);
        representer.addProperty("hobbies", List.class);
        representer.addProperty("addresses", Map.class);

        Yaml yaml = new Yaml(representer);

        String output = yaml.dump(users);
        System.out.println(output);
    }
}

上面的代碼使用對象圖API將兩個User對象序列化為YAML格式的數據。

其中,Representer類用於配置如何將Java對象圖轉換為YAML格式的數據,其addClassTag方法用於添加類別標籤,addProperty方法用於添加類屬性。

  • 將YAML格式的數據反序列化為Java對象圖
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Representer;
import org.yaml.snakeyaml.Yaml;

import java.util.List;
import java.util.Map;

public class User {
    private String name;
    private int age;
    private List<String> hobbies;
    private Map<String, String> addresses;

    // 省略構造方法和getter/setter方法

    public static void main(String[] args) {
        String input = "--- !!seq\n"
                + "- !user\n"
                + "  name: 張三\n"
                + "  age: 20\n"
                + "  hobbies:\n"
                + "  - 籃球\n"
                + "  - 游泳\n"
                + "  addresses:\n"
                + "    work: 中國北京\n"
                + "    home: 中國上海\n"
                + "- !user\n"
                + "  name: 李四\n"
                + "  age: 30\n"
                + "  hobbies:\n"
                + "  - 書法\n"
                + "  - 繪畫\n"
                + "  addresses:\n"
                + "    work: 中國廣州\n"
                + "    home: 中國深圳";

        Representer representer = new Representer();
        representer.addClassTag(User.class, new Tag("!user"));
        representer.addProperty("name", String.class);
        representer.addProperty("age", int.class);
        representer.addProperty("hobbies", List.class);
        representer.addProperty("addresses", Map.class);

        Yaml yaml = new Yaml(representer);

        List<User> users = yaml.loadAs(input, List.class);

        for (User user : users) {
            System.out.println("姓名:" + user.getName());
            System.out.println("年齡:" + user.getAge());
            System.out.println("愛好:" + user.getHobbies());
            System.out.println("地址:" + user.getAddresses());
        }
    }
}

上面的代碼使用對象圖

原創文章,作者:OTGCJ,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/313637.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
OTGCJ的頭像OTGCJ
上一篇 2025-01-07 09:44
下一篇 2025-01-07 09:44

相關推薦

發表回復

登錄後才能評論