修改前配置文件 src/main/resources/conf/config.yaml
sys:
info:
name: "macOs"
version: "10.15.4"
cpu:
name: "Intel Core i5"
counts: 4
hz: "1.4GHz"
cnName: "英特酷睿i5"
test:
name: 123
alist:
- java
- python
- golang
使用properties的key-value,方式修改yaml文件中的属性值。 支持属性值(value)的类型:字符串,数字,List集合。
对属性值为Map类型的可能出现问题,不建议使用。修改之后yaml格式有些许变化
package com.kiki.refresh.resource;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import java.io.FileWriter;
import java.io.InputStream;
import java.util.*;
@Slf4j
@Component
public class YamlConfigs {
private final static DumperOptions OPTIONS = new DumperOptions();
static{
//设置yaml读取方式为块读取
OPTIONS.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
OPTIONS.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);
OPTIONS.setPrettyFlow(false);
}
/**
* 将yaml配置文件转化成map
* fileName 默认是resources目录下的yaml文件, 如果yaml文件在resources子目录下,需要加上子目录 比如:conf/config.yaml
* @param fileName
* @return
*/
public Map getYamlToMap(String fileName){
LinkedHashMap yamls = new LinkedHashMap<>();
Yaml yaml = new Yaml();
try {
@Cleanup InputStream in = YamlConfigs.class.getClassLoader().getResourceAsStream(fileName);
yamls = yaml.loadAs(in,LinkedHashMap.class);
}catch (Exception e){
log.error("{} load failed !!!" , fileName);
}
return yamls;
}
/**
* key格式:aaa.bbb.ccc
* 通过properties的方式获取yaml中的属性值
* @param key
* @param yamlMap
* @return
*/
public Object getValue(String key, Map yamlMap){
String[] keys = key.split("[.]");
Object o = yamlMap.get(keys[0]);
if(key.contains(".")){
if(o instanceof Map){
return getValue(key.substring(key.indexOf(".")+1),(Map)o);
}else {
return null;
}
}else {
return o;
}
}
/**
* 使用递归的方式设置map中的值,仅适合单一属性
* key的格式: "server.port"
* server.port=111
*
**/
public Map setValue(String key,Object value) {
Map result = new LinkedHashMap<>();
String[] keys = key.split("[.]");
int i = keys.length - 1;
result.put(keys[i], value);
if (i > 0) {
return setValue(key.substring(0, key.lastIndexOf(".")), result);
}
return result;
}
public Map setValue(Map map, String key, Object value){
String[] keys = key.split("\\.");
int len = keys.length;
Map temp = map;
for(int i = 0; i< len-1; i++){
if(temp.containsKey(keys[i])){
temp = (Map)temp.get(keys[i]);
}else {
return null;
}
if(i == len-2){
temp.put(keys[i+1],value);
}
}
for(int j = 0; j < len - 1; j++){
if(j == len -1){
map.put(keys[j],temp);
}
}
return map;
}
/**
* 修改yaml中属性的值
* @param key key是properties的方式: aaa.bbb.ccc (key不存在不修改)
* @param value 新的属性值 (新属性值和旧属性值一样,不修改)
* @param yamlName
* @return true 修改成功,false 修改失败。
*/
public boolean updateYaml(String key, @Nullable Object value, String yamlName){
Map yamlToMap = this.getYamlToMap(yamlName);
if(null == yamlToMap) {
return false;
}
Object oldVal = this.getValue(key, yamlToMap);
//未找到key 不修改
if(null == oldVal){
log.error("{} key is not found",key);
return false;
}
//不是最小节点值,不修改
if(oldVal instanceof Map){
log.error("input key is not last node {}",key);
return false;
}
//新旧值一样 不修改
if(value.equals(oldVal)){
log.info("newVal equals oldVal, newVal: {} , oldVal: {}",value,oldVal);
return false;
}
Yaml yaml = new Yaml(OPTIONS);
String path = this.getClass().getClassLoader().getResource(yamlName).getPath();
try {
Map resultMap = this.setValue(yamlToMap, key, value);
if(resultMap != null){
yaml.dump(this.setValue(yamlToMap,key,value),new FileWriter(path));
return true;
}else {
return false;
}
}catch (Exception e){
log.error("yaml file update failed !");
log.error("msg : {} ",e.getMessage());
log.error("cause : {} ",e.getCause());
}
return false;
}
public static void main(String[] args) {
YamlConfigs configs = new YamlConfigs();
Map yamlToMap = configs.getYamlToMap("conf/config.yaml");
System.out.println(yamlToMap);
boolean b = configs.updateYaml("sys.cpu.name", "Intel Core i7", "conf/config.yaml");
System.out.println(b);
System.out.println(configs.getYamlToMap("conf/config.yaml"));
}
}
执行结果
源码目录的yaml文件不会被修改,classes目录下的yaml文件被修改
sys:
info:
name: macOs
version: 10.15.4
cpu:
name: Intel Core i7
counts: 4
hz: 1.4GHz
cnName: 英特酷睿i5
test:
name: 123
alist:
- java
- python
- golang