yml转properties java工具类

yml转properties java工具类

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
 
/**
 * Yaml 配置文件转 Properties 配置文件工具类
 * @author https://zyqok.blog.csdn.net/
 * @since 2021/08/24
 */
public class YmlUtils {
    public static void main(String[] args) {
        castProperties("test.yml");
    }
 
    /**
     * 将 yml 文件转化为 properties 文件
     *
     * @param ymlFileName 工程根目录下(非resources目录)的 yml 文件名称(如:abc.yml)
     * @return List<Node> 每个Nyml 文件中每行对应解析的数据
     */
    public static List<YmlNode> castProperties(String ymlFileName) {
        if (ymlFileName == null || ymlFileName.isEmpty() || !ymlFileName.endsWith(".yml")) {
            throw new RuntimeException("请输入yml文件名称!!");
        }
        File ymlFile = new File(ymlFileName);
        if (!ymlFile.exists()) {
            throw new RuntimeException("工程根目录下不存在 " + ymlFileName + "文件!!");
        }
        String fileName = ymlFileName.split(".yml", 2)[0];
        // 获取文件数据
        String yml = read(ymlFile);
        List<YmlNode> nodeList = getNodeList(yml);
        // 去掉多余数据,并打印
        String str = printNodeList(nodeList);
        // 将数据写入到 properties 文件中
        String propertiesName = fileName + ".properties";
        File file = new File(propertiesName);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try (FileWriter writer = new FileWriter(file)) {
            writer.write(str);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return nodeList;
    }
 
    /**
     * 将yml转化为porperties文件,并获取转化后的键值对
     *
     * @param ymlFileName 工程根目录下的 yml 文件名称
     * @return 转化后的 porperties 文件键值对Map
     */
    public static Map<String, String> getPropertiesMap(String ymlFileName) {
        Map<String, String> map = new HashMap<>();
        List<YmlNode> list = castProperties(ymlFileName);
        for (YmlNode node : list) {
            if (node.getKey().length() > 0) {
                map.put(node.getKey(), node.getValue());
            }
        }
        return map;
    }
 
    private static String read(File file) {
        if (Objects.isNull(file) || !file.exists()) {
            return "";
        }
        try (FileInputStream fis = new FileInputStream(file)) {
            byte[] b = new byte[(int) file.length()];
            fis.read(b);
            return new String(b, StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }
 
    private static String printNodeList(List<YmlNode> nodeList) {
        StringBuilder sb = new StringBuilder();
        for (YmlNode node : nodeList) {
            if (node.getLast().equals(Boolean.FALSE)) {
                continue;
            }
            if (node.getEmptyLine().equals(Boolean.TRUE)) {
                System.out.println();
                sb.append("\r\n");
                continue;
            }
            // 判断是否有行级注释
            if (node.getHeadRemark().length() > 0) {
                String s = "# " + node.getHeadRemark();
                System.out.println(s);
                sb.append(s).append("\r\n");
                continue;
            }
            // 判断是否有行末注释 (properties中注释不允许末尾注释,故而放在上面)
            if (node.getTailRemark().length() > 0) {
                String s = "# " + node.getTailRemark();
                System.out.println(s);
                sb.append(s).append("\r\n");
            }
            //
            String kv = node.getKey() + "=" + node.getValue();
            System.out.println(kv);
            sb.append(kv).append("\r\n");
        }
        return sb.toString();
    }
 
    private static List<YmlNode> getNodeList(String yml) {
        String[] lines = yml.split("\r\n");
        List<YmlNode> nodeList = new ArrayList<>();
        Map<Integer, String> keyMap = new HashMap<>();
        Set<String> keySet = new HashSet<>();
        for (String line : lines) {
            YmlNode node = getNode(line);
            if (node.getKey() != null && node.getKey().length() > 0) {
                int level = node.getLevel();
                if (level == 0) {
                    keyMap.clear();
                    keyMap.put(0, node.getKey());
                } else {
                    int parentLevel = level - 1;
                    String parentKey = keyMap.get(parentLevel);
                    String currentKey = parentKey + "." + node.getKey();
                    keyMap.put(level, currentKey);
                    node.setKey(currentKey);
                }
            }
            keySet.add(node.getKey() + ".");
            nodeList.add(node);
        }
        // 标识是否最后一级
        for (YmlNode each : nodeList) {
            each.setLast(getNodeLast(each.getKey(), keySet));
        }
        return nodeList;
    }
 
    private static boolean getNodeLast(String key, Set<String> keySet) {
        if (key.isEmpty()) {
            return true;
        }
        key = key + ".";
        int count = 0;
        for (String each : keySet) {
            if (each.startsWith(key)) {
                count++;
            }
        }
        return count == 1;
    }
 
    private static YmlNode getNode(String line) {
        YmlNode node = new YmlNode();
        // 初始化默认数据(防止NPE)
        node.setEffective(Boolean.FALSE);
        node.setEmptyLine(Boolean.FALSE);
        node.setHeadRemark("");
        node.setKey("");
        node.setValue("");
        node.setTailRemark("");
        node.setLast(Boolean.FALSE);
        node.setLevel(0);
        // 空行,不处理
        String trimStr = line.trim();
        if (trimStr.isEmpty()) {
            node.setEmptyLine(Boolean.TRUE);
            return node;
        }
        // 行注释,不处理
        if (trimStr.startsWith("#")) {
            node.setHeadRemark(trimStr.replaceFirst("#", "").trim());
            return node;
        }
        // 处理值
        String[] strs = line.split(":", 2);
        // 拆分后长度为0的,属于异常数据,不做处理
        if (strs.length == 0) {
            return node;
        }
        // 获取键
        node.setKey(strs[0].trim());
        // 获取值
        String value;
        if (strs.length == 2) {
            value = strs[1];
        } else {
            value = "";
        }
        // 获取行末备注
        String tailRemark = "";
        if (value.contains(" #")) {
            String[] vs = value.split("#", 2);
            if (vs.length == 2) {
                value = vs[0];
                tailRemark = vs[1];
            }
        }
        node.setTailRemark(tailRemark.trim());
        node.setValue(value.trim());
        // 获取当前层级
        int level = getNodeLevel(line);
        node.setLevel(level);
        node.setEffective(Boolean.TRUE);
        return node;
    }
 
    private static int getNodeLevel(String line) {
        if (line.trim().isEmpty()) {
            return 0;
        }
        char[] chars = line.toCharArray();
        int count = 0;
        for (char c : chars) {
            if (c != ' ') {
                break;
            }
            count++;
        }
        return count / 2;
    }
}
 
class YmlNode {
 
    /** 层级关系 */
    private Integer level;
    /** 键 */
    private String key;
    /** 值 */
    private String value;
    /** 是否为空行 */
    private Boolean emptyLine;
    /** 当前行是否为有效配置 */
    private Boolean effective;
    /** 头部注释(单行注释) */
    private String headRemark;
    /** 末尾注释 */
    private String tailRemark;
    /** 是否为最后一层配置 */
    private Boolean last;
 
    public Boolean getLast() {
        return last;
    }
 
    public void setLast(Boolean last) {
        this.last = last;
    }
 
    public Integer getLevel() {
        return level;
    }
 
    public void setLevel(Integer level) {
        this.level = level;
    }
 
    public String getKey() {
        return key;
    }
 
    public void setKey(String key) {
        this.key = key;
    }
 
    public String getValue() {
        return value;
    }
 
    public void setValue(String value) {
        this.value = value;
    }
 
    public Boolean getEmptyLine() {
        return emptyLine;
    }
 
    public void setEmptyLine(Boolean emptyLine) {
        this.emptyLine = emptyLine;
    }
 
    public Boolean getEffective() {
        return effective;
    }
 
    public void setEffective(Boolean effective) {
        this.effective = effective;
    }
 
    public String getHeadRemark() {
        return headRemark;
    }
 
    public void setHeadRemark(String headRemark) {
        this.headRemark = headRemark;
    }
 
    public String getTailRemark() {
        return tailRemark;
    }
 
    public void setTailRemark(String tailRemark) {
        this.tailRemark = tailRemark;
    }
 
}

原文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以编写一个静态方法的工具类,用于获取指定模块下的`application-druid.yml`文件中的数据库连接信息。以下是一个示例代码: ```java import org.springframework.boot.env.YamlPropertySourceLoader; import org.springframework.core.env.PropertySource; import org.springframework.core.io.ClassPathResource; import java.io.IOException; import java.util.Map; public class DatabaseConfigUtil { public static DatabaseConfig getDatabaseConfig(String moduleName) throws IOException { YamlPropertySourceLoader loader = new YamlPropertySourceLoader(); ClassPathResource resource = new ClassPathResource(moduleName + "/application-druid.yml"); PropertySource<?> propertySource = loader.load("database", resource); Map<String, Object> properties = (Map<String, Object>) propertySource.getSource(); Map<String, Object> dataSourceProperties = (Map<String, Object>) properties.get("spring.datasource"); String url = (String) dataSourceProperties.get("url"); String username = (String) dataSourceProperties.get("username"); String password = (String) dataSourceProperties.get("password"); return new DatabaseConfig(url, username, password); } } ``` 在上述代码中,我们编写了一个静态方法`getDatabaseConfig`,该方法接收一个`moduleName`参数,表示目标模块的名称。我们首先使用`YamlPropertySourceLoader`加载目标模块下的`application-druid.yml`文件,然后从加载后的属性源中获取`spring.datasource`的属性值,最后将属性值封装到一个`DatabaseConfig`对象中返回。 假设`DatabaseConfig`类的构造方法如下: ```java public class DatabaseConfig { private final String url; private final String username; private final String password; public DatabaseConfig(String url, String username, String password) { this.url = url; this.username = username; this.password = password; } public String getUrl() { return url; } public String getUsername() { return username; } public String getPassword() { return password; } } ``` 在使用该工具类时,只需要调用`getDatabaseConfig`方法并传入目标模块的名称即可,例如: ```java try { DatabaseConfig databaseConfig = DatabaseConfigUtil.getDatabaseConfig("moduleA"); String url = databaseConfig.getUrl(); String username = databaseConfig.getUsername(); String password = databaseConfig.getPassword(); // 使用获取到的数据库连接信息进行操作 } catch (IOException e) { e.printStackTrace(); } ``` 需要注意的是,在使用该工具类时,需要确保目标模块的`application-druid.yml`文件能够在classpath下被找到。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值