在SpringBoot里面我们经常会读取配置文件
目前常用的配置文件有两种格式:.properties 和 .yml,它们的区别主要是书写格式不同
1).properties
app.user.name = javastack
2).yml
app:
user:
name: javastack
另外,.yml 格式不支持 @PropertySource 注解导入配置。
今天主要介绍通过第三方工具来读取配置文件
SnakeYaml是一个完整的YAML1.1规范Processor,支持UTF-8/UTF-16,支持Java对象的序列化/反序列化,支持所有YAML定义的类型(map,omap,set,常量,具体参考
快速使用
要使用SnakeYaml,首先引入maven依赖:
org.yaml
snakeyaml
1.17
我们来完成一个最简单的yaml解析例子:
@Test
public void testLoad() {
String yamlStr = "key: hello yaml";
Yaml yaml = new Yaml();
Object ret = yaml.load(yamlStr);
System.out.println(ret);
}
结果输出:{key=hello yaml}
简介解释:
1,使用Yaml类,创建一个Yaml对象,所有的解析操作都是从这个对象开始;
2,声明了一个yaml的字符串(当然也可以使用yaml文档等),定义了一个对象:key: hello yaml;
3,使用Yaml对象的load方法 public Object load(String yaml)加载一段yaml字符串,返回解析之后的对象;
可以看到,实际创建的是一个Map:LinkedHashMap。
load/loadAll/loadAs 方法使用
Yaml的load方法可以传入多种参数类型:
public Object load(String yaml)
public Object load(InputStream io)
public Object load(Reader io)
三个方法都是通过传入的不同类型的内容,解析得到结果对象。需要注意一点的是,SnakeYaml通过读入的内容是否包含BOM头来判断输入流的编码格式。如果不包含BOM头,默认为UTF-8编码。
接下来上代码:
public class YmlUtil {
private static Map ymls = new HashMap<>();
private static ThreadLocal nowFileName = new ThreadLocal<>();
public static Logger log = LoggerFactory.getLogger(YmlUtil.class);
public static void loadYml(String fileName) throws IOException {
nowFileName.set(fileName);
try {
String outpath = System.getProperty("user.dir")+File.separator;
InputStream in = new FileInputStream(new File(outpath + String.format("%s.yml",fileName)));
if (!ymls.containsKey(fileName)) {
ymls.put(fileName, new Yaml().loadAs(in, LinkedHashMap.class));
}
}catch (IOException e){
InputStream in = YmlUtil.class.getClassLoader().getResourceAsStream(String.format("%s.yml",fileName));
if (!ymls.containsKey(fileName)) {
ymls.put(fileName, new Yaml().loadAs(in, LinkedHashMap.class));
}
}
}
public static Object getValue(String key) throws Exception {
String[] keys = key.split("[.]");
Map ymlInfo = (Map) ymls.get(nowFileName.get()).clone();
for (int i = 0; i < keys.length; i++) {
String keyStr = keys[i];
Object value = null;
if (StringUtils.isNumericSpace(keyStr)){
value = ymlInfo.get(Integer.parseInt(keyStr));
}else{
value = ymlInfo.get(keyStr);
}
if (i < keys.length - 1) {
ymlInfo = (Map) value;
} else if (value == null) {
return null;
} else {
return value;
}
}
throw new RuntimeException("It's impossible to get here...");
}
public static String getValue(String fileName, String key) {
Object obj = null;
try {
loadYml(fileName);
obj = getValue(key);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
String value = StringUtil.nullToString(obj);
log.info(String.format("Get value [ %s ] by key [ %s ]",value,key));
return value;
}
public static String calibrationMap(String fileName,String firstKey,Map parameterMap){
Object obj = null;
String prompt = null;
try {
loadYml(fileName);
obj = getValue(firstKey);
if (obj instanceof Map){
prompt = calibration((Map) obj,parameterMap);
}else{
throw new RuntimeException("Check the calibration.YML file for format errors");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return prompt;
}
public static String calibration(Map calibrationMap,Map parameterMap){
Iterator> iterator = calibrationMap.entrySet().iterator();
String prompt = null;
while (iterator.hasNext()){
Map.Entry entry = iterator.next();
String key = entry.getKey();
if (parameterMap.containsKey(key)){
Object parameterKey = parameterMap.get(key);
boolean flag = StringUtil.isEmpty(parameterKey);
if (flag){
prompt = entry.getValue();
break;
}
}else{
prompt = entry.getValue();
break;
}
}
return prompt;
}
public static void main (String [] args){
String path = YmlUtil.class.getClassLoader().getResource("application.yml").getPath();
System.err.println(path);
}
}