天天看點

snakeyaml生成yaml檔案空值顯示問題

    snakeyaml開源庫,可以很友善的加載和生成yaml檔案,普通的加載,其實springboot項目都可以實作,在生成yaml檔案的時候,有幾個問題需要注意,第一個是格式問題,另外一個就是空值問題。

    使用snakeyaml庫需要加入如下依賴:

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

    如下所示,預設yaml格式,集合顯示帶有中括号。

package com.yaml;

import org.yaml.snakeyaml.Yaml;

import java.io.StringWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class YamlTest {
    public static void main(String[] args) {
        Map<String,Object> map = new HashMap<>(){
            {
                put("name","buejee");
                put("age",18);
                put("email",null);
                put("company","");
                put("language", Arrays.asList("java","python","cplusplus"));
            }
        };
        Yaml yaml = new Yaml();
        StringWriter writer = new StringWriter();
        yaml.dump(map,writer);
        System.out.println(writer.toString());
    }
}
           

    列印結果:

snakeyaml生成yaml檔案空值顯示問題

     這個結果有一個很明顯的問題,就是集合沒有按照預期的格式展示,我們希望展示如下所示:

name: buejee
company: ''
language: 
  - java
  - python
  - cplusplus
age: 18
email: null
           

    我們需要通過DumperOptions來設定yaml檔案流格式,這裡設定塊級顯示。

DumperOptions options  = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(options);
           

    這樣之後,顯示稍微好一點:

snakeyaml生成yaml檔案空值顯示問題

    但是縮進不是很理想,這裡我們設定縮進:

options.setIndentWithIndicator(true);
options.setIndicatorIndent(2);
           

   這樣,顯示好多了:

snakeyaml生成yaml檔案空值顯示問題

    這裡面,還是有兩個問題,空字元"",顯示為'',null值顯示為了null,其實我們希望null顯示空。經過摸索,發現可以通過自定義Representer來達到顯示為空的效果。

package com.yaml;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Represent;
import org.yaml.snakeyaml.representer.Representer;
public class RepresenterNull extends Representer {
    public RepresenterNull(){
        super();
        this.nullRepresenter = new NullRepresenter();
    }
    private class NullRepresenter implements Represent{

        @Override
        public Node representData(Object o) {
            return representScalar(Tag.NULL,"");
        }
    }
}
           

    在執行個體化Yaml的時候,傳入RepresenterNull執行個體。

Yaml yaml = new Yaml(new RepresenterNull(),options);
           

    展示效果:

snakeyaml生成yaml檔案空值顯示問題

    不過,對于字元串=""的情況,并沒有轉為空,但是我們可以在指派的時候判斷,如果equals(""),那麼就指派null也可以。

    這裡改變輸出到檔案:

FileWriter writer = new FileWriter(new File("test.yaml"));
yaml.dump(map,writer);
           

    最後生成的yaml檔案如下所示:

snakeyaml生成yaml檔案空值顯示問題

    完整代碼:

package com.yaml;

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

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class YamlTest {
    public static void main(String[] args) throws IOException {
        Map<String,Object> map = new HashMap<>(){
            {
                put("name","buejee");
                put("age",18);
                put("email",null);
                put("company",null);
                put("language", Arrays.asList("java","python","cplusplus"));
            }
        };
        DumperOptions options  = new DumperOptions();
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        options.setIndentWithIndicator(true);
        options.setIndicatorIndent(2);
        Yaml yaml = new Yaml(new RepresenterNull(),options);
        //StringWriter writer = new StringWriter();
        //yaml.dump(map,writer);
        //System.out.println(writer.toString());
        FileWriter writer = new FileWriter(new File("test.yaml"));
        yaml.dump(map,writer);
    }
}
           

       snakeyaml生成yaml檔案,設定塊級格式,自定義空值顯示就介紹完了。讓我最高興的就是空值顯示問題的解決,因為在工作中正好用到了,特此記錄一下。