properties转yml

目前搜索到的大部分代码都存在以下问题:

  • 复杂结构解析丢失
  • 解析后顺序错乱

所以自己写了一个,经过不充分测试,基本满足使用。可以直接在线使用 在线地址
除了yml和properties互转之外,还可以生成代码、sql转json等,可以去用一下,用爱发电,感谢支持!
在这里插入图片描述
源码:

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Deng.Weiping
 * @since 2023/11/28 13:57
 */
@Slf4j
public class PropertiesUtil {

    /**
     * yaml 转 Properties
     *
     * @param input
     * @return
     */
    public static String castToProperties(String input) {
        Map<String, Object> propertiesMap = new LinkedHashMap<>();
        Map<String, Object> yamlMap = new Yaml().load(input);
        flattenMap("", yamlMap, propertiesMap);
        StringBuffer strBuff = new StringBuffer();
        propertiesMap.forEach((key, value) -> strBuff.append(key)
                .append("=")
                .append(value)
                .append(StrUtil.LF));
        return strBuff.toString();
    }

    /**
     * Properties 转 Yaml
     *
     * @param input
     * @return
     */
    public static String castToYaml(String input) {
        try {
            Map<String, Object> properties = readProperties(input);
            return properties2Yaml(properties);
        } catch (Exception e) {
            log.error("property 转 Yaml 转换失败", e);
        }
        return null;
    }

    private static Map<String, Object> readProperties(String input) throws IOException {
        Map<String, Object> propertiesMap = new LinkedHashMap<>(); // 使用 LinkedHashMap 保证顺序
        for (String line : input.split(StrUtil.LF)) {
            if (StrUtil.isNotBlank(line)) {
                // 使用正则表达式解析每一行中的键值对
                Pattern pattern = Pattern.compile("\\s*([^=\\s]*)\\s*=\\s*(.*)\\s*");
                Matcher matcher = pattern.matcher(line);
                if (matcher.matches()) {
                    String key = matcher.group(1);
                    String value = matcher.group(2);
                    propertiesMap.put(key, value);
                }
            }
        }
        return propertiesMap;
    }

    /**
     * 递归 Map 集合,转为 Properties集合
     *
     * @param prefix
     * @param yamlMap
     * @param treeMap
     */
    private static void flattenMap(String prefix, Map<String, Object> yamlMap, Map<String, Object> treeMap) {
        yamlMap.forEach((key, value) -> {
            String fullKey = prefix + key;
            if (value instanceof LinkedHashMap) {
                flattenMap(fullKey + ".", (LinkedHashMap) value, treeMap);
            } else if (value instanceof ArrayList) {
                List values = (ArrayList) value;
                for (int i = 0; i < values.size(); i++) {
                    String itemKey = String.format("%s[%d]", fullKey, i);
                    Object itemValue = values.get(i);
                    if (itemValue instanceof String) {
                        treeMap.put(itemKey, itemValue);
                    } else {
                        flattenMap(itemKey + ".", (LinkedHashMap) itemValue, treeMap);
                    }
                }
            } else {
                treeMap.put(fullKey, value.toString());
            }
        });
    }

    /**
     * properties 格式转化为 yaml 格式字符串
     *
     * @param properties
     * @return
     */
    private static String properties2Yaml(Map<String, Object> properties) {
        if (CollUtil.isEmpty(properties)) {
            return null;
        }
        Map<String, Object> map = parseToMap(properties);
        StringBuffer stringBuffer = map2Yaml(map);
        return stringBuffer.toString();
    }

    /**
     * 递归解析为 LinkedHashMap
     *
     * @param propMap
     * @return
     */
    private static Map<String, Object> parseToMap(Map<String, Object> propMap) {
        Map<String, Object> resultMap = new LinkedHashMap<>();
        try {
            if (CollectionUtils.isEmpty(propMap)) {
                return resultMap;
            }
            propMap.forEach((key, value) -> {
                if (key.contains(".")) {
                    String currentKey = key.substring(0, key.indexOf("."));
                    if (resultMap.get(currentKey) != null) {
                        return;
                    }
                    Map<String, Object> childMap = getChildMap(propMap, currentKey);
                    Map<String, Object> map = parseToMap(childMap);
                    resultMap.put(currentKey, map);
                } else {
                    resultMap.put(key, value);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultMap;
    }


    /**
     * 获取拥有相同父级节点的子节点
     *
     * @param propMap
     * @param currentKey
     * @return
     */
    private static Map<String, Object> getChildMap(Map<String, Object> propMap, String currentKey) {
        Map<String, Object> childMap = new LinkedHashMap<>();
        try {
            propMap.forEach((key, value) -> {
                if (key.contains(currentKey + ".")) {
                    key = key.substring(key.indexOf(".") + 1);
                    childMap.put(key, value);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        return childMap;
    }

    /**
     * map集合转化为yaml格式字符串
     *
     * @param map
     * @return
     */
    public static StringBuffer map2Yaml(Map<String, Object> map) {
        //默认deep 为零,表示不空格,deep 每加一层,缩进两个空格
        return map2Yaml(map, 0);
    }

    /**
     * 把Map集合转化为yaml格式 String字符串
     *
     * @param propMap map格式配置文件
     * @param deep    树的层级,默认deep 为零,表示不空格,deep 每加一层,缩进两个空格
     * @return
     */
    private static StringBuffer map2Yaml(Map<String, Object> propMap, int deep) {
        StringBuffer yamlBuffer = new StringBuffer();
        try {
            if (CollectionUtils.isEmpty(propMap)) {
                return yamlBuffer;
            }
            String space = getSpace(deep);
            for (Map.Entry<String, Object> entry : propMap.entrySet()) {
                Object valObj = entry.getValue();
                if (entry.getKey().contains("[") && entry.getKey().contains("]")) {
                    String key = entry.getKey().substring(0, entry.getKey().indexOf("[")) + ":";
                    yamlBuffer.append(space + key + "\n");
                    propMap.forEach((itemKey, itemValue) -> {
                        if (itemKey.startsWith(key.substring(0, entry.getKey().indexOf("[")))) {
                            yamlBuffer.append(getSpace(deep + 1) + "- ");
                            if (itemValue instanceof Map) {
                                StringBuffer valStr = map2Yaml((Map<String, Object>) itemValue, 0);
                                String[] split = valStr.toString().split(StrUtil.LF);
                                for (int i = 0; i < split.length; i++) {
                                    if (i > 0) {
                                        yamlBuffer.append(getSpace(deep + 2));
                                    }
                                    yamlBuffer.append(split[i]).append(StrUtil.LF);
                                }
                            } else {
                                yamlBuffer.append(itemValue + "\n");
                            }
                        }
                    });
                    break;
                } else {
                    String key = space + entry.getKey() + ":";
                    if (valObj instanceof String) { //值为value 类型,不用再继续遍历
                        yamlBuffer.append(key + " " + valObj + "\n");
                    } else if (valObj instanceof List) { //yaml List 集合格式
                        yamlBuffer.append(key + "\n");
                        List<String> list = (List<String>) entry.getValue();
                        String lSpace = getSpace(deep + 1);
                        for (String str : list) {
                            yamlBuffer.append(lSpace + "- " + str + "\n");
                        }
                    } else if (valObj instanceof Map) { //继续递归遍历
                        Map<String, Object> valMap = (Map<String, Object>) valObj;
                        yamlBuffer.append(key + "\n");
                        StringBuffer valStr = map2Yaml(valMap, deep + 1);
                        yamlBuffer.append(valStr.toString());
                    } else {
                        yamlBuffer.append(key + " " + valObj + "\n");
                    }
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return yamlBuffer;
    }

    /**
     * 获取缩进空格
     *
     * @param deep
     * @return
     */
    private static String getSpace(int deep) {
        StringBuffer buffer = new StringBuffer();
        if (deep == 0) {
            return "";
        }
        for (int i = 0; i < deep; i++) {
            buffer.append("  ");
        }
        return buffer.toString();
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/199324.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

sqli-labs(6)

27. 过滤了union和select 使用双写绕过 有报错信息使用报错注入 1and(extractvalue(1,concat(0x5c,database())))and11 1and(updatexml(1,concat(0x7e,database(),0x7e),1))and11 1and(extractvalue(1,concat(0x5c,(selseselectlectect(group_concat(table_name))from(inform…

JVM 类加载

① 类加载过程 从上面的图片我们可以看出整个 JVM 执行的流程中&#xff0c;和程序员关系最密切的就是类加载的过程了&#xff0c;所以 接下来我们来看下类加载的执行流程。 对于一个类来说&#xff0c;它的生命周期是这样的&#xff1a; 其中前 5 步是固定的顺序并且也是类加载…

三十、elasticsearch集群

目录 一、集群的概念 1、节点 2、索引 3、分片和副本 二、集群的架构 三、集群的部署方式 1、单主节点 2、多主节点 3、安全集群 四、搭建ES集群 1、elasticsearch中集群节点有不同的职责划分 2、elasticsearch中的每个节点角色都有自己不同的职责&#xff0c;因此…

DockerCompose修改某个服务的配置(添加或编辑端口号映射)后如何重启单个服务使其生效

场景 docker-compose入门以及部署SpringBootVueRedisMysql(前后端分离项目)以若依前后端分离版为例&#xff1a; docker-compose入门以及部署SpringBootVueRedisMysql(前后端分离项目)以若依前后端分离版为例_docker-compose部署java mysql redis-CSDN博客 上面讲了docker c…

水库大坝安全在线监测系统守护水利工程的坚实屏障

随着科技的发展&#xff0c;水库大坝的安全监测已经进入了一个全新的时代。过去&#xff0c;我们无法实时监测大坝的安全状况&#xff0c;只能在灾难发生后进行补救&#xff0c;现在&#xff0c;通过WX-DB1水库大坝安全在线监测系统&#xff0c;我们能够在第一时间掌握大坝的运…

Android 如何让路由器或者其他AP设备获取到主机名

问题原因: 连接到AP设备后,发现主机名在路由器或者其他AP设备都无法正常显示 抓取tcpdump log发现DHCP request option中没有携带host name(Option 12)字段 如下图所示 修改方法: 将config_dhcp_client_hostname配置true后,可以看到host name了 具体代码逻辑如下 pack…

事件代理?

1.什么是事件代理&#xff1f; 事件代理也叫事件委托&#xff0c;只指定一个事件处理程序&#xff0c;就可以管理某一类型得事件。 可以简单理解为&#xff0c;事件代理就是将本应该绑定子元素事件绑定给父元素代理。它的优点就是&#xff1a;减少事件得执行&#xff0c;减少浏…

【技术干货】宇视IPC音频问题解决步骤

近期技术人员从宇视官网下载sdk进行二次开发时&#xff0c;在启动实时直播&#xff0c;并通过回调函数拿到流数据&#xff0c;发现没有音频流数据。 通过下面的数据发现&#xff0c;codeType此字段一直是28&#xff0c;代表的是H.264数据&#xff0c;但未没发现有音频的数据包…

2. 两数相加

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 …

常见气体爆炸下限

国标中关于常见气体爆炸下限说明&#xff0c;特此记录 特此记录 anlog 2023年11月29日

LeetCode Hot100 739.每日温度

题目&#xff1a; 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 方法&…

AWS连甩3项Serverless创新,高效创建和操作缓存,用AI优化资源配置性价比

云创科技11月28日拉斯维加斯报道&#xff0c;在一年一度的AWS re:Invent首日&#xff0c;AWS实用计算高级副总裁Peter DeSantis延续Monday Night Live的传统&#xff0c;发表主题演讲并分享了AWS数据库和分析产品组合中的3项Serverless创新&#xff0c;以帮助客户在任何规模下分…

Java——》线性数据结构

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

Linux系统编程 day06 进程间通信

进程间通信 1. 进程间通信的概念2. 匿名管道pipe3. 命名管道FIFO4. 内存映射区 1. 进程间通信的概念 在Linux的环境下&#xff0c;进程地址空间是相互独立的&#xff0c;每个进程有着各自不同的用户地址空间。一个进程不能访问另一个进程中的内容&#xff0c;要进行数据交换必…

elFinder ZIP 参数注入导致命令注入 (CVE-2021-32682)

漏洞描述 elFinder 是一个用于 Web 的开源文件管理器&#xff0c;使用 jQuery UI 用 JavaScript 编写。 在 elFinder 2.1.48 及更早版本中发现一个参数注入漏洞。此漏洞可能允许攻击者在托管 elFinder PHP 连接器的服务器上执行任意命令&#xff0c;即使配置最少也是如此。这…

SpringBoot : ch11 整合RabbitMQ

前言 在当今的互联网时代&#xff0c;消息队列成为了构建高可靠、高性能系统的重要组件之一。RabbitMQ作为一个可靠、灵活的消息中间件&#xff0c;被广泛应用于各种分布式系统中。 本篇博客将介绍如何使用Spring Boot整合RabbitMQ&#xff0c;实现消息的发送和接收。通过这种…

浅析函数防抖节流

防抖和节流都是前端开发中常用的优化性能的技术。 一、定义 防抖&#xff1a; 防抖指的是在事件触发后&#xff0c;在规定的时间内若再次触发&#xff0c;则重新计时&#xff0c;直到规定时间内没有再次触发事件&#xff0c;才执行事件处理。这样可以避免在短时间内频繁地触发…

SSL证书实惠品牌——JoySSL

随着互联网的普及和发展&#xff0c;网络安全问题日益严重。为了保护网站数据的安全&#xff0c;越来越多的网站开始使用SSL证书。JoySSL证书作为一款高性价比的SSL证书&#xff0c;受到了广泛的关注和好评。 目前市面上主流的证书基本上都是国外证书&#xff0c;也就是说你在验…

爬虫程序为什么一次写不好?需要一直修改BUG?

从我学习编程以来&#xff0c;尤其是在学习数据抓取采集这方面工作&#xff0c;经常遇到改不完的代码&#xff0c;我毕竟从事了8年的编程工作&#xff0c;算不上大佬&#xff0c;但是也不至于那么差。那么哪些因素导致爬虫代码一直需要修改出现BUG&#xff1f;下面来谈谈我的感…

一种新的基于物理的AlGaN/GaN HFET紧凑模型

标题&#xff1a;A new physics-based compact model for AlGaN/GaN HFETs (IEEE MTT-S International Microwave Symposium) 摘要 摘要 - 针对AlGaN/GaN HFET&#xff0c;提出了一种无拟合参数的物理解析模型。对于非饱和操作&#xff0c;建立了两个接入区和栅极下方I-V特性的…