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