3.3.1 加载yml文件
-
编写yaml工厂,用于加载yml文件
package com.czxy.yaml; import java.io.InputStream; /** * 用于处理 application.yml文件 * 1. 加载application.yml文件 * 2. yaml工具类进行解析 * Map<String, Map<String, Map<....>> > * twoMap.put("port", 9090) * oneMap.put("server", twoMap) * 3. 将特殊的map转换,另一种map * Map<String, Object> * map.put("server.port",9090) public class YamlFactory { private static InputStream yamlInputStream; /** * 加载yaml文件 */ private static void loadFile() { //获得类加载器(当前类名.class.getClassLoader()) ClassLoader classLoader = YamlFactory.class.getClassLoader(); //通过类加载器获得资源文件流 yamlInputStream = classLoader.getResourceAsStream("application.yml"); //校验 if(yamlInputStream == null) { throw new RuntimeException("Missing configuration file application.yml"); } } public static void init() { //加载yaml文件 loadFile(); System.out.println(yamlInputStream); //解下yaml文件 } }
-
测试类
package com.czxy; import com.czxy.yaml.YamlFactory; public class TestYaml { public static void main(String[] args) { YamlFactory.init(); } }
3.3.2 解析yaml文件
package com.czxy.yaml;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.BaseConstructor;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.representer.Representer;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
* 用于处理 application.yml文件
* 1. 加载application.yml文件
* 2. yaml工具类进行解析
* Map<String, Map<String, Map<....>> >
* twoMap.put("port", 9090)
* oneMap.put("server", twoMap)
* 3. 将特殊的map转换,另一种map
* Map<String, Object>
* map.put("server.port",9090)
* @author 桐叔
* @email liangtong@itcast.cn
* @description
*/
public class YamlFactory {
//yaml文件流
private static InputStream yamlInputStream;
//yaml文件中的数据
private static Map<String,Object> yamlData;
/**
* 加载yaml文件
*/
private static void loadFile() {
//获得类加载器(当前类名.class.getClassLoader())
ClassLoader classLoader = YamlFactory.class.getClassLoader();
//通过类加载器获得资源文件流
yamlInputStream = classLoader.getResourceAsStream("application.yml");
//校验
if(yamlInputStream == null) {
throw new RuntimeException("Missing configuration file application.yml");
}
}
/**
* 解析yaml
* yaml核心工具类参数参考:https://vimsky.com/examples/detail/java-class-org.yaml.snakeyaml.representer.Representer.html
* http://www.yiidian.com/sources/java_source/org.yaml.snakeyaml.representer.Representer.html
*/
private static void parseYaml() {
//参数设置
LoaderOptions loaderOptions = new LoaderOptions();
loaderOptions.setAllowDuplicateKeys(false); //key不允许重复
loaderOptions.setMaxAliasesForCollections(Integer.MAX_VALUE);
loaderOptions.setAllowRecursiveKeys(true); //key允许递归
BaseConstructor constructor = new SafeConstructor(loaderOptions);
Representer representer = new Representer();
DumperOptions dumperOptions = new DumperOptions();
// dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
//核心类
Yaml yaml = new Yaml(constructor,representer, dumperOptions);
//加载yaml文件
Map<String,Object> data = yaml.load(yamlInputStream);
if(data != null) {
yamlData = data;
} else {
yamlData = new HashMap<>();
}
System.out.println(yamlData);
}
public static void init() {
//加载yaml文件
loadFile();
//解析yaml文件
parseYaml();
}
}
3.3.3 处理yaml数据
- 从spring boot源码中获得4个方法
package com.czxy.yaml;
import com.sun.istack.internal.Nullable;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.BaseConstructor;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.representer.Representer;
import java.io.InputStream;
import java.util.*;
/**
* 用于处理 application.yml文件
* 1. 加载application.yml文件
* 2. yaml工具类进行解析
* Map<String, Map<String, Map<....>> >
* twoMap.put("port", 9090)
* oneMap.put("server", twoMap)
* 3. 将特殊的map转换,另一种map
* Map<String, Object>
* map.put("server.port",9090)
* @author 桐叔
* @email liangtong@itcast.cn
* @description
*/
public class YamlFactory {
//yaml文件流
private static InputStream yamlInputStream;
//yaml文件中的数据
private static Map<String,Object> yamlData;
/**
* 加载yaml文件
*/
private static void loadFile() {
//获得类加载器(当前类名.class.getClassLoader())
ClassLoader classLoader = YamlFactory.class.getClassLoader();
//通过类加载器获得资源文件流
yamlInputStream = classLoader.getResourceAsStream("application.yml");
//校验
if(yamlInputStream == null) {
throw new RuntimeException("Missing configuration file application.yml");
}
}
/**
* 解析yaml
* yaml核心工具类参数参考:https://vimsky.com/examples/detail/java-class-org.yaml.snakeyaml.representer.Representer.html
*/
private static void parseYaml() {
//参数设置
LoaderOptions loaderOptions = new LoaderOptions();
loaderOptions.setAllowDuplicateKeys(false); //key不允许重复
loaderOptions.setMaxAliasesForCollections(Integer.MAX_VALUE);
loaderOptions.setAllowRecursiveKeys(true); //key允许递归
BaseConstructor constructor = new SafeConstructor(loaderOptions);
Representer representer = new Representer();
DumperOptions dumperOptions = new DumperOptions();
// dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
//核心类
Yaml yaml = new Yaml(constructor,representer, dumperOptions);
//加载yaml文件
Map<String,Object> data = yaml.load(yamlInputStream);
if(data != null) {
yamlData = getFlattenedMap(data);
} else {
yamlData = new HashMap<>();
}
System.out.println(yamlData);
}
/**
* 初始化
*/
public static void init() {
//加载yaml文件
loadFile();
//解析yaml文件
parseYaml();
}
/**
* 将无限极,转换成 A.B.C 形式的key
* @param source
* @return
*/
private static Map<String, Object> getFlattenedMap(Map<String, Object> source) {
Map<String, Object> result = new LinkedHashMap<>();
buildFlattenedMap(result, source, (String)null);
return result;
}
private static void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, @Nullable String path) {
source.forEach((key, value) -> {
if (hasText(path)) {
if (key.startsWith("[")) {
key = path + key;
}
else {
key = path + '.' + key;
}
}
if (value instanceof String) {
result.put(key, value);
}
else if (value instanceof Map) {
// Need a compound key
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) value;
buildFlattenedMap(result, map, key);
}
else if (value instanceof Collection) {
// Need a compound key
@SuppressWarnings("unchecked")
Collection<Object> collection = (Collection<Object>) value;
if (collection.isEmpty()) {
result.put(key, "");
}
else {
int count = 0;
for (Object object : collection) {
buildFlattenedMap(result, Collections.singletonMap(
"[" + (count++) + "]", object), key);
}
}
}
else {
result.put(key, (value != null ? value : ""));
}
});
}
/**
* 判断是否是文本
* @param str
* @return
*/
private static boolean hasText(@Nullable String str) {
return str != null && !str.isEmpty() && containsText(str);
}
private static boolean containsText(CharSequence str) {
int strLen = str.length();
for(int i = 0; i < strLen; ++i) {
if (!Character.isWhitespace(str.charAt(i))) {
return true;
}
}
return false;
}
}
3.3.4 获得数据
- 将初始化方法private化,提供静态代码块进行初始化
提供2个方法用于获得数据
package com.czxy.yaml;
import com.sun.istack.internal.Nullable;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.BaseConstructor;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.representer.Representer;
import java.io.InputStream;
import java.util.*;
/**
* 用于处理 application.yml文件
* 1. 加载application.yml文件
* 2. yaml工具类进行解析
* Map<String, Map<String, Map<....>> >
* twoMap.put("port", 9090)
* oneMap.put("server", twoMap)
* 3. 将特殊的map转换,另一种map
* Map<String, Object>
* map.put("server.port",9090)
* @author 桐叔
* @email liangtong@itcast.cn
* @description
*/
public class YamlFactory {
//yaml文件流
private static InputStream yamlInputStream;
//yaml文件中的数据
private static Map<String,Object> yamlData;
/**
* 加载yaml文件
*/
private static void loadFile() {
//获得类加载器(当前类名.class.getClassLoader())
ClassLoader classLoader = YamlFactory.class.getClassLoader();
//通过类加载器获得资源文件流
yamlInputStream = classLoader.getResourceAsStream("application.yml");
//校验
if(yamlInputStream == null) {
throw new RuntimeException("Missing configuration file application.yml");
}
}
/**
* 解析yaml
* yaml核心工具类参数参考:https://vimsky.com/examples/detail/java-class-org.yaml.snakeyaml.representer.Representer.html
*/
private static void parseYaml() {
//参数设置
LoaderOptions loaderOptions = new LoaderOptions();
loaderOptions.setAllowDuplicateKeys(false); //key不允许重复
loaderOptions.setMaxAliasesForCollections(Integer.MAX_VALUE);
loaderOptions.setAllowRecursiveKeys(true); //key允许递归
BaseConstructor constructor = new SafeConstructor(loaderOptions);
Representer representer = new Representer();
DumperOptions dumperOptions = new DumperOptions();
// dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
//核心类
Yaml yaml = new Yaml(constructor,representer, dumperOptions);
//加载yaml文件
Map<String,Object> data = yaml.load(yamlInputStream);
if(data != null) {
yamlData = getFlattenedMap(data);
} else {
yamlData = new HashMap<>();
}
System.out.println(yamlData);
}
/**
* 静态代码会在当前类加载到内存中自动执行
*/
static {
//进行初始化
init();
}
/**
* 初始化
*/
private static void init() {
//加载yaml文件
loadFile();
//解析yaml文件
parseYaml();
}
/**
* 获得数据,如果没有返回null
* @param key
* @return
*/
public static <T> T getValue(String key) {
return getValue(key, null);
}
/**
* 获得数据,如果没有,返回默认值
* @param key A.B.C
* @param defaultValue 默认值
* @return
*/
public static <T> T getValue(String key, T defaultValue) {
//从map获得数据
T value = (T)yamlData.get(key);
return value != null ? value : defaultValue;
}
/**
* 将无限极,转换成 A.B.C 形式的key
* @param source
* @return
*/
private static Map<String, Object> getFlattenedMap(Map<String, Object> source) {
Map<String, Object> result = new LinkedHashMap<>();
buildFlattenedMap(result, source, (String)null);
return result;
}
private static void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, @Nullable String path) {
source.forEach((key, value) -> {
if (hasText(path)) {
if (key.startsWith("[")) {
key = path + key;
}
else {
key = path + '.' + key;
}
}
if (value instanceof String) {
result.put(key, value);
}
else if (value instanceof Map) {
// Need a compound key
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) value;
buildFlattenedMap(result, map, key);
}
else if (value instanceof Collection) {
// Need a compound key
@SuppressWarnings("unchecked")
Collection<Object> collection = (Collection<Object>) value;
if (collection.isEmpty()) {
result.put(key, "");
}
else {
int count = 0;
for (Object object : collection) {
buildFlattenedMap(result, Collections.singletonMap(
"[" + (count++) + "]", object), key);
}
}
}
else {
result.put(key, (value != null ? value : ""));
}
});
}
/**
* 判断是否是文本
* @param str
* @return
*/
private static boolean hasText(@Nullable String str) {
return str != null && !str.isEmpty() && containsText(str);
}
private static boolean containsText(CharSequence str) {
int strLen = str.length();
for(int i = 0; i < strLen; ++i) {
if (!Character.isWhitespace(str.charAt(i))) {
return true;
}
}
return false;
}
}