You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SnakeYAML 2.0反序列化出现Global tag is not allowed异常的解决方法

SnakeYAML 2.0自定义对象序列化与反序列化问题解决

问题场景

自定义User类如下:

package ir.sharif;

import java.util.ArrayList;
import java.util.List;

public class User {
    int id;
    String username;
    String password;
    List<User> friends = new ArrayList<>();

    public User(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public User() {
    }

    // 省略getter和setter方法
}

使用SnakeYAML 2.0序列化User对象的代码:

package ir.sharif;

import org.yaml.snakeyaml.Yaml;

import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws IOException {
        User user = new User();
        user.setId(10);
        user.setUsername("Jack");
        user.setPassword("jackSparrow2023");
        List<User> friends = new ArrayList<>();
        friends.add(new User(1, "Trent", "FCB"));
        friends.add(new User(2, "Jordan", "LFC"));
        user.setFriends(friends);

        Yaml yaml = new Yaml();
        yaml.dump(user, new FileWriter("src/main/resources/sample.yml"));
    }
}

生成的sample.yml包含类标签:

!!ir.sharif.User
friends:
- friends: []
  id: 1
  password: FCB
  username: Trent
- friends: []
  id: 2
  password: LFC
  username: Jordan
id: 10
password: jackSparrow2023
username: Jack

尝试直接用yaml.load()反序列化时抛出异常:

Exception in thread "main" Global tag is not allowed: tag:yaml.org,2002:ir.sharif.User
 in 'reader', line 1, column 1:
    !!ir.sharif.User
    ^

原因分析

SnakeYAML 2.0为了安全,默认禁用了全局自定义标签,序列化时自动添加的!!ir.sharif.User属于自定义全局标签,反序列化时会被拦截。

解决方案

方法1:反序列化时指定目标类(无需修改序列化逻辑)

直接使用loadAs()方法明确指定要反序列化的类,无需删除yml中的标签:

package ir.sharif;

import org.yaml.snakeyaml.Yaml;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class Main {
    public static void main(String[] args) throws IOException {
        Yaml yaml = new Yaml();
        try (Reader reader = new FileReader("src/main/resources/sample.yml")) {
            // 明确指定目标类
            User user = yaml.loadAs(reader, User.class);
            System.out.println(user.getUsername()); // 输出Jack
        }
    }
}

方法2:配置SnakeYAML允许自定义标签

如果需要保留load()方法的使用,可以创建Yaml实例时配置Constructor,允许指定的自定义标签:

package ir.sharif;

import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.Yaml;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class Main {
    public static void main(String[] args) throws IOException {
        // 构造器指定目标类,允许该类的标签
        Constructor constructor = new Constructor(User.class);
        Yaml yaml = new Yaml(constructor);
        try (Reader reader = new FileReader("src/main/resources/sample.yml")) {
            User user = yaml.load(reader);
            System.out.println(user.getUsername()); // 输出Jack
        }
    }
}

方法3:序列化时不输出类标签

如果不需要yml文件中的类标签,可以在序列化时配置DumperOptions关闭标签输出,后续反序列化直接用loadAs():

package ir.sharif;

import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws IOException {
        User user = new User();
        user.setId(10);
        user.setUsername("Jack");
        user.setPassword("jackSparrow2023");
        List<User> friends = new ArrayList<>();
        friends.add(new User(1, "Trent", "FCB"));
        friends.add(new User(2, "Jordan", "LFC"));
        user.setFriends(friends);

        DumperOptions options = new DumperOptions();
        options.setExplicitTag(false); // 关闭显式标签输出
        Yaml yaml = new Yaml(options);
        yaml.dump(user, new FileWriter("src/main/resources/sample.yml"));
    }
}

生成的yml文件不再包含!!ir.sharif.User标签,反序列化时直接用loadAs()即可正常解析。

内容的提问来源于stack exchange,提问作者Harry Redwood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 12:45:31