如何配置SnakeYAML的DumperOptions生成嵌套结构并避免键重复?
配置SnakeYAML生成嵌套YAML并避免键重复
要生成嵌套形式的YAML而非扁平点分隔格式,核心在于使用嵌套的Map数据结构,再配合合适的DumperOptions配置;而键重复问题则需要通过自定义Representer来解决。
1. 核心:用嵌套Map替代扁平键值对
如果当前用"key.value1"这类带点的字符串作为键,SnakeYAML会直接输出扁平格式。正确做法是构建嵌套Map结构:
Map<String, Object> nestedMap = new HashMap<>(); nestedMap.put("value1", 3); nestedMap.put("value2", 5); Map<String, Object> rootMap = new HashMap<>(); rootMap.put("key", nestedMap);
2. 配置DumperOptions确保嵌套格式输出
通过DumperOptions设置块风格和缩进,保证生成层级分明的嵌套结构:
DumperOptions options = new DumperOptions(); // 设置为块风格,是生成嵌套缩进格式的关键 options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); // 设置层级缩进量 options.setIndent(2); // 禁用默认的YAML起始标记--- options.setExplicitStart(false);
3. 处理键重复问题
SnakeYAML默认允许YAML出现重复键,若要避免,需自定义Representer,在序列化时检查并抛出异常:
class NoDuplicateKeysRepresenter extends Representer { @Override protected void representMapping(NodeTuple nodeTuple, boolean flowStyle) { MappingNode mappingNode = (MappingNode) nodeTuple.getValue(); Set<Object> keys = new HashSet<>(); for (NodeTuple tuple : mappingNode.getValue()) { Object key = representData(tuple.getKey()).getValue(); if (!keys.add(key)) { throw new IllegalArgumentException("发现重复键: " + key); } } super.representMapping(nodeTuple, flowStyle); } }
完整代码示例
import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.nodes.MappingNode; import org.yaml.snakeyaml.nodes.NodeTuple; import org.yaml.snakeyaml.representer.Representer; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; public class SnakeYamlDemo { public static void main(String[] args) { // 构建嵌套数据结构 Map<String, Object> nestedMap = new HashMap<>(); nestedMap.put("value1", 3); nestedMap.put("value2", 5); Map<String, Object> rootMap = new HashMap<>(); rootMap.put("key", nestedMap); // 测试重复键:取消注释会触发异常 // rootMap.put("key", "重复值"); // 配置输出选项 DumperOptions options = new DumperOptions(); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); options.setIndent(2); options.setExplicitStart(false); // 使用自定义Representer拦截重复键 Representer representer = new NoDuplicateKeysRepresenter(); Yaml yaml = new Yaml(representer, options); // 输出嵌套格式YAML System.out.println(yaml.dump(rootMap)); } static class NoDuplicateKeysRepresenter extends Representer { @Override protected void representMapping(NodeTuple nodeTuple, boolean flowStyle) { MappingNode mappingNode = (MappingNode) nodeTuple.getValue(); Set<Object> keys = new HashSet<>(); for (NodeTuple tuple : mappingNode.getValue()) { Object key = representData(tuple.getKey()).getValue(); if (!keys.add(key)) { throw new IllegalArgumentException("发现重复键: " + key); } } super.representMapping(nodeTuple, flowStyle); } } }
执行代码后会输出目标嵌套格式:
key: value1: 3 value2: 5
如果添加重复键,代码会直接抛出IllegalArgumentException,避免生成无效的重复键YAML。
内容的提问来源于stack exchange,提问作者Batimonster
相关产品推荐
相关产品推荐

