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);
}
}