修改前配置文件 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<String,Object> getYamlToMap(String fileName){
        LinkedHashMap<String, Object> 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<String,Object> 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<String,Object>)o);
            }else {
                return null;
            }
        }else {
            return o;
        }
    }

    /**
     * 使用递归的方式设置map中的值,仅适合单一属性
     * key的格式: "server.port"
     * server.port=111
     *
     **/
    public Map<String,Object> setValue(String key,Object value) {
        Map<String, Object> 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<String,Object> setValue(Map<String,Object> 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<String, Object> 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<String, Object> 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<String, Object> 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

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐