目录

引入依赖 

snakeyaml支持通过map,json,java对象生成yaml

整理好的2个方法

关于引用


引入依赖 

jackson-dataformat-yaml 2.11.3版本包含 snakeyaml 1.26

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-yaml</artifactId>
    <version>2.11.3</version>    
 </dependency>

或者直接引入snakeyaml 。写这篇笔记的时间是2020.11.24 最新版本为1.27

 <!-- https://mvnrepository.com/artifact/org.yaml/snakeyaml -->
       <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.27</version>
        </dependency>

 snakeyaml 开发wiki

snakeyaml支持通过map,json,java对象生成yaml

public static void main(String[] args) {
        Map<String,String> map = new LinkedHashMap<>();
        map.put("A","ABC");
        map.put("B","BBB");
        map.put("C","CCC");
         //转储选项设置
        DumperOptions options = new DumperOptions();
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);//通常使用的yaml格式
        options.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);//标量格式
        Yaml yaml = new Yaml(options);
        String str = yaml.dump(map);
        System.out.println(str);
    }

ScalarStyle.PLAIN 无样式 (默认) 

A: ABC
B: BBB
C: CCC

 ScalarStyle.SINGLE_QUOTED 单引号将输出的key,value括起来

'A': 'ABC'
'B': 'BBB'
'C': 'CCC'

 ScalarStyle.DOUBLE_QUOTED 双引号

"A": "ABC"
"B": "BBB"
"C": "CCC"

ScalarStyle.FOLDED 折叠

 "A": >-
  ABC
"B": >-
  BBB
"C": >-
  CCC

ScalarStyle.LITERAL 字面 

"A": |-
  ABC
"B": |-
  BBB
"C": |-
  CCC

普通的yaml文件,snakeyaml都能满足,注意控制好对象或者map的层级结构。如果想生成key的首字母是大写的yaml,目前只能用map,如果使用Javabean,即使把变量名设置成大写,也会输出成首字母小写。

如果想输出 value 中包含双引号的值 比如

Map<String,String> map = new LinkedHashMap<>();

map.put("A","ABC");

dump之后会变成

A:ABC

想输出成

A:"ABC"

我试过 map.put("A","\"ABC\"")

结果dump出来的是

A:'"ABC"'

通过询问作者,在转储的时候,如果双引号是value的一部分,会使用单引号转义。

我的做法是先用yaml.dump输出String 再用正则过滤掉多余的单引号 再使用FileWriter 生成yaml文件。

整理好的2个方法

    /**
     * 打印输出转储的yaml
     * @param configTx 参数
     */
    public static void outPutConfigTxYaml(Map<String, Object> configTx) {
        DumperOptions options = new DumperOptions();
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        Yaml yaml = new Yaml(options);
        String str = yaml.dump(configTx);
        str = formatYamlStr(str);
        System.out.println(str);
    }

    /**
     * 生成yaml文件
     * @param configTx 参数
     */
    public static String createConfigTxYaml(Map<String, Object> configTx) {
        DumperOptions options = new DumperOptions();
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        Yaml yaml = new Yaml(options);
        String str = yaml.dump(configTx);
        str = formatYamlStr(str);
        try {
            FileWriter fw = new FileWriter("data/files/configtx00.yaml");
            fw.write(str);
            fw.flush();
            fw.close();
            System.out.println("生成yaml完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

补充一下格式化方法

可以根据需求自己定义格式化的方法

    private static final String REGEX_BRACKET = "[\\[\\]]";
    private static final String REGEX_BACKSLASH = "\\\\";
    private static final String REGEX_INSIDE = "''";
    private static final String REGEX_HEAD = "'\"";
    private static final String REGEX_TAIL = "\"'";
    private static final String SINGLE_QUOTED = "'";
    private static final String DOUBLE_QUOTED = "\"";

    /**
     * 格式化yaml字符串
     *
     * @param str
     * @return 格式化后的字符串
     */
    private static String formatYamlStr(String str) {
        Pattern p = Pattern.compile(REGEX_BRACKET);
        Matcher m = p.matcher(str);
        //过滤字符串 删掉多余中括号
        str = m.replaceAll("").trim();
        p = Pattern.compile(REGEX_BACKSLASH);
        m = p.matcher(str);
        str = m.replaceAll("");
        p = Pattern.compile(REGEX_INSIDE);
        m = p.matcher(str);
        //被单引号转义的单引号 '' 还原成 '
        str = m.replaceAll(SINGLE_QUOTED);
        p = Pattern.compile(REGEX_HEAD);
        m = p.matcher(str);
        //被单引号转义的双引号结尾 "' 还原成 "
        str = m.replaceAll(DOUBLE_QUOTED);
        p = Pattern.compile(REGEX_TAIL);
        m = p.matcher(str);
        //被单引号转义的双引号开头 '" 还原成 "
        return m.replaceAll(DOUBLE_QUOTED);
    }

关于引用

snake yaml 在将map转储yaml文件时会自动识别key:value相同的内容做别名引用,在第一次出现时起一个别名如:id001,在后面出现时自动使用别名引用之前的内容。

下面这个例子会演示生成的别名及引用

Organizations:
- &id001#此处起了第一个别名 使用*+别名 即 *id001 引用别名包含的部分即蓝色字体内容
  Name: org1MSP
  ID: org1MSP
  MSPDir: /mnt/fabric-production/server/org1/orderers/msp
  Policies:
    Readers:
      Type: Signature
      Rule: "OR('org1MSP.member')"
    Writers:
      Type: Signature
      Rule: "OR('org1MSP.member')"
    Admins:
      Type: Signature
      Rule: "OR('org1MSP.admin')"
  OrdererEndpoints:
  - orderer0-org1:7050

- &id006
  Name: org2MSP
  ID: org2MSP
  MSPDir: /mnt/fabric-production/server/org2/peers/msp
  Policies:
    Readers:
      Type: Signature
      Rule: "OR('org2MSP.admin', 'org2MSP.peer', 'org2MSP.client')"
    Writers:
      Type: Signature
      Rule: "OR('org2MSP.admin', 'org2MSP.client')"
    Admins:
      Type: Signature
      Rule: "OR('org2MSP.admin')"
    Endorsement:
      Type: Signature
      Rule: "OR('org2MSP.peer')"
  AnchorPeers:
  - Host: peer0-org2
    Port: 7051
Capabilities:
  Channel: &id003
    V2_0: true
  Orderer: &id002
    V2_0: true
  Application: &id009
    V2_0: true
Application: &id008
  Policies:
    Readers:
      Type: ImplicitMeta
      Rule: "ANY Readers"
    Writers:
      Type: ImplicitMeta
      Rule: "ANY Writers"
    Admins:
      Type: ImplicitMeta
      Rule: "MAJORITY Admins"
    LifecycleEndorsement:
      Type: ImplicitMeta
      Rule: "MAJORITY Endorsement"
    Endorsement:
      Type: ImplicitMeta
      Rule: "MAJORITY Endorsement"
  Capabilities:
    V2_0: true
Orderer: &id005
  OrdererType: etcdraft
  BatchTimeout: 2s
  Organizations: *id001#在此引用了别名id001的内容
  Addresses:
  - orderer0-org1:7050

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐