Java Yml格式转换为Properties问题
作者:Chengdu.S
本文介绍了作者编写一个Java工具类来解决在线YAML到Properties转换时属性内容遗漏的问题,通过遍历YAML文件的树结构,作者成功实现了属性的完整转换,总结指出,该工具类适用于多种数据类型,并且代码简洁易懂
问题引入
使用在线的yml转换properties, 发现有属性内容漏了,网站地址https://tooltt.com/yaml2properties/。
于是自己动手写个转换工具类,自测过多个 yml 文件,目前没发现遗漏的。
需要转换的yaml文件如下
spring: application: name: xtoon-sys-server cloud: nacos: config: server-addr: localhost:8848 file-extension: yaml enabled: true boot: admin: client: url: http://localhost:5001 username: admin password: admin instance: prefer-ip: true management: health: redis: enabled: false endpoint: health: show-details: always endpoints: web: exposure: include: "*"
在线转换网站转换的结果
spring.application.name=xtoon-sys-server spring.cloud.nacos.config.server-addr=localhost:8848 spring.cloud.nacos.config.file-extension=yaml spring.boot.admin.client.url=http://localhost:5001 spring.boot.admin.client.username=admin spring.boot.admin.client.password=admin management.endpoint.health.show-details=always management.endpoints.web.exposure.include=*
正确的转换结果应该如下
spring.application.name=xtoon-sys-server spring.cloud.nacos.config.server-addr=localhost:8848 spring.cloud.nacos.config.file-extension=yaml spring.cloud.nacos.config.enabled=true spring.boot.admin.client.url=http://localhost:5001 spring.boot.admin.client.username=admin spring.boot.admin.client.password=admin spring.boot.admin.client.instance.prefer-ip=true management.health.redis.enabled=false management.endpoint.health.show-details=always management.endpoints.web.exposure.include=*
在线网站转换结果截图如下
对比原始文本和转换结果,发现少了几个属性
spring.cloud.nacos.config.enabled=true spring.boot.admin.client.instance.prefer-ip=true management.health.redis.enabled=false
这几个结果有些特征,value值是boolean类型的。不知道还有没有其它类型的数据会有遗漏的?
转换代码
导入yaml读取jar
<dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>1.33</version> </dependency>
Java 代码
package com.scd.tool; import org.yaml.snakeyaml.Yaml; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Set; /** * @author James */ public class YamlToProperties { public static void main(String[] args) { Yaml yaml = new Yaml(); String filePath = "file/yaml/bootstrap.yml"; try (InputStream inputStream = new FileInputStream(filePath)) { Object object = yaml.load(inputStream); List<String> resultList = travelRootWithResult(object); System.out.println(resultList); } catch (IOException e) { throw new RuntimeException(e); } } private static List<String> travelRootWithResult(Object object) { List<String> resultList = new ArrayList<>(); if (object instanceof LinkedHashMap) { LinkedHashMap map = (LinkedHashMap) object; Set<Object> keySet = map.keySet(); for (Object key : keySet) { List<String> keyList = new ArrayList<>(); keyList.add((String) key); travelTreeNode(map.get(key), keyList, resultList); } } return resultList; } private static void travelTreeNode(Object obj, List<String> keyList, List<String> resultList) { if (obj instanceof LinkedHashMap) { LinkedHashMap linkedHashMap = (LinkedHashMap) obj; linkedHashMap.forEach((key, value) -> { if (value instanceof LinkedHashMap) { keyList.add((String) key); travelTreeNode(value, keyList, resultList); keyList.remove(keyList.size() - 1); } else { StringBuilder result = new StringBuilder(); for (String strKey : keyList) { result.append(strKey).append("."); } result.append(key).append("=").append(value); System.out.println(result); resultList.add(result.toString()); } }); } else { StringBuilder result = new StringBuilder(); result.append(keyList.get(0)).append("=").append(obj); System.out.println(result); resultList.add(result.toString()); } } }
运行结果如下,对比之后发现没有出现遗漏的
spring.application.name=xtoon-sys-server spring.cloud.nacos.config.server-addr=localhost:8848 spring.cloud.nacos.config.file-extension=yaml spring.cloud.nacos.config.enabled=true spring.boot.admin.client.url=http://localhost:5001 spring.boot.admin.client.username=admin spring.boot.admin.client.password=admin spring.boot.admin.client.instance.prefer-ip=true management.health.redis.enabled=false management.endpoint.health.show-details=always management.endpoints.web.exposure.include=*
大家使用的时候只需要改一下filePath
代码解读
可以把yml 看成多个树,问题就转换成了遍历树的问题,我们需要获取树的路径以及子节点。
树的路径是properties的key, 叶子节点是properties的value
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。