YAML
Yaml是一種“是一個可讀性高並且容易被人類閱讀,容易和腳本語言交互,用來表達資料序列的編程語言。”類似於XML但比XML更簡潔,語法詳見
http://www.ruanyifeng.com/blog/2016/07/yaml.html
在JAVA中也有相關的類庫可以進行解析YAML
准備工作
這里使用gradle加入依賴
compile 'org.yaml:snakeyaml:1.17'
之后就可以使用了
load
先上代碼
@Test
public void load() throws FileNotFoundException{
//初始化Yaml解析器
Yaml yaml = new Yaml();
File f=new File("test.yaml");
//讀入文件
Object result= yaml.load(new FileInputStream(f));
System.out.println(result.getClass());
System.out.println( result);
}
----test.yaml---
a: 1
b: 2
----輸出---
class java.util.LinkedHashMap
{a=1, b=2}
這里load方法支持String,InputStream,Reader作為輸入
loadall
在一個yaml文件中可以存入多組配置並使用loadAll進行讀取,多組之間使用三個橫杠分開
@Test
public void loadall() throws FileNotFoundException {
Yaml yaml = new Yaml();
File f = new File("test.yaml");
Iterable<Object> result = yaml.loadAll(new FileInputStream(f));
for (Object obj : result) {
System.out.println(obj.getClass());
System.out.println(obj);
}
}
----test.yaml---
a: 1
b: 2
---
c: 3
----輸出---
class java.util.LinkedHashMap
{a=1, b=2}
class java.util.LinkedHashMap
{c=3}
這里返回的是一個Iterable,每個對象的解析是在遍歷到的時候進行的是懶加載的
java對象
snakeyaml還支持普通java類型的讀取
@Test
public void loadPojo() throws FileNotFoundException {
Yaml yaml = new Yaml();
File f = new File("test.yaml");
Map result= (Map) yaml.load(new FileInputStream(f));
System.out.println(result);
System.out.println(result.get("pojo"));
System.out.println(result.get("pojo2"));
}
public class Pojo {
public String name;
public Pojo(String name){
this.name=name
}
@Override
public String toString(){
return "name->"+name;
}
}
----test.yaml---
pojo: !!yaml.Pojo {name: name}
pojo2: !!yaml.Pojo [ name]
這里簡單定義了一個pojo然后在配置文件中有兩種方式第一種(使用大括號{})是通過變量名進行賦值,第二種(使用方括號[])是通過構造方法進行賦值
dump
同時還支持將對象反向編譯成yaml配置
@Test
public void dump() throws FileNotFoundException {
Yaml yaml = new Yaml();
Pojo p=new Pojo();
p.name="name";
System.out.println( yaml.dump(p));
}
----輸出---
!!yaml.Pojo {name: name}
Yaml配置
上面使用的都是YAML的無參構造方法,其實YAML在構造方法中還有可以配置參數
主要有如下4個
constructor
用於配置構造對象的創建過程
representer
用於配置yaml文件中對應tag響應解析成的對象
Representer representer = new Representer();
representer.addClassTag(Car.class, new Tag("!car"));//這里!car就會使用Car類型來解析,而不需要再配置文件中寫全car的包名
representer.addClassTag(Wheel.class, Tag.MAP);//會使用Wheel對map的類型進行解析
dumpoption
這個是在dump時,控制輸出的寬度,對齊,類類型等相關信息
resolver
用於隱式識別對應類型,只要符合了對應的pattern就會使用對應的tag進行解析
yaml.addImplicitResolver(new Tag("!dice"), Pattern.compile("\d+d\d+"), "123456789");
alias merge
yaml支持別名引用(&用於起別名 *用於引用),以及merger(<<:)
- &anchor
boolean: true
integer: 3
- <<: *anchor
integer: 7
----輸出---
[{boolean=true, integer=3}, {integer=7, boolean=true}]
可以看到第二個map自動merge了應用的boolean而integer覆蓋了原來的值3
備注
參考官方文檔:https://bitbucket.org/asomov/snakeyaml/wiki/Documentation