天天看點

yaml文檔讀取

pom依賴

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

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

工具代碼

package com.donfaquir.axe.zk.yaml;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

import java.util.Map;

/**
 * @author: 
 * @description: 使用snakeyaml架構讀取yaml檔案
 * @date Create in 2018/12/28 15:08
 * @modified By:
 */
@SuppressWarnings("unchecked")
public class SnakeYaml {
    private static Logger log = LoggerFactory.getLogger(SnakeYaml.class);

    /** 查詢路徑分隔符,類似:dubbo.registry.address */
    private static final String SEPARATOR = ".";
    /** 檔案路徑 */
    private String filePath;
    /** yaml檔案操作入口 */
    private Yaml yaml;
    /** 辨別是否建立Yaml執行個體 */
    private Boolean isInit;

    public SnakeYaml(String filePath){
        this.filePath = filePath;
        this.yaml = new Yaml();
        this.isInit = true;
    }

    /**
     * 根據key值路徑,擷取指定字元串的值
     * <p>
     * 在yaml檔案中,形如:
     * <blockquote><pre>
     * first:
     *   second:
     *     third: value
     * </pre></blockquote>
     * 可以通過下面的調用方式擷取"value"
     * <blockquote><pre>
     * String str = get("first.second.third");
     * </pre></blockquote>
     * 最多支援層級為五層;更深層的資料無法通過該方法擷取,會傳回key路徑。
     * 層級高于五層,可以調用 {@link SnakeYaml#getYamlObject()} 擷取配置檔案得Object對象,手動封裝擷取
     *
     * @param keyPath   取值的key路徑
     * @return          傳回對應的值
     */

    public Object get(String keyPath){
        if(null == keyPath || !this.isInit){
            return null;
        }

        //如果給定的取值路徑是多級路徑,
        //隻支援最多五級路徑
        String[] keys;

        if(keyPath.contains(SEPARATOR)){
            keys = keyPath.split("\\.");
        }else{
            return getFirstOrderValue(keyPath);
        }
        return getValue(yaml.load(this.getClass().getClassLoader().getResourceAsStream(this.filePath)), keys, keys.length);
    }

    /**
     * 擷取值
     * 如果key路徑中隻有一層,直接擷取值
     * 如果key路徑中有多層,會多次調用該方法,判斷路徑中的key是否有對應的值,也就是進行非空判斷
     * @param load  yaml檔案加載對象
     * @param keys  key路徑中的值組成的數組
     * @param step  key路徑中的層數
     * @return      擷取的值
     */
    private Object getValue(Object load,String[] keys,int step){
        if(null == load || null == keys){
            return null;
        }
        if(step > keys.length){
            return null;
        }
        switch (step){
            case 1:
                Map<String, Object> load1 = (Map<String, Object>) load;
                return load1.get(keys[0]);
            case 2:
                Object load22 = getValue(load,keys,1);
                if(null != load22){
                    Map<String, Object> load2 = (Map<String, Object>) load22;
                    return load2.get(keys[1]);
                }
                return null;
            case 3:
                Object load33 = getValue(load,keys,2);
                if(null != load33){
                    Map<String, Object> load3 = (Map<String, Object>) load33;
                    return load3.get(keys[2]);
                }
                return null;
            case 4:
                Object load44 = getValue(load,keys,3);
                if(null != load44){
                    Map<String, Object> load4 = (Map<String, Object>) load44;
                    return load4.get(keys[3]);
                }
                return null;
            case 5:
                Object load55 = getValue(load,keys,4);
                if(null != load55){
                    Map<String, Object> load5 = (Map<String, Object>) load55;
                    return load5.get(keys[4]);
                }
                return null;
            default:
                return null;
        }
    }


    /**
     * 擷取yaml檔案中,第一層key對應的值
     * @param keyName       key值
     * @return              對應的value
     */
    public Object getFirstOrderValue(String keyName){
        if(keyName == null){
            return null;
        }
        if(keyName.contains(SEPARATOR)){
            this.get(keyName);
        }
        Map<String, Object> load = (Map<String, Object>) yaml.load(this.getClass().getClassLoader().getResourceAsStream(this.filePath));
        return load == null ? null : load.get(keyName);
    }

    /**
     * 如果擷取資料的層級大于5級,調用此方法擷取檔案的Object對象
     * 使用者手動擷取對應資料
     * @return              檔案的Object對象
     */
    public Object getYamlObject(){
        return yaml.load(this.getClass().getClassLoader().getResourceAsStream(this.filePath));
    }

    /**
     * 封裝成指定的執行個體對象
     * @param clazz         執行個體類型
     * @param <T>           占位符
     * @return              執行個體對象
     */
    public <T> T getObjectsFromYaml(Class<T> clazz){
        return yaml.loadAs(this.getClass().getClassLoader().getResourceAsStream(this.filePath), clazz);
    }




}
           

繼續閱讀