当前位置:   article > 正文

解析yml文件 转换 Map_missing map key

missing map key

起因

有一个需求是把一个yml文件解析成HashMap格式的数据,文件内容如下

  1. spring:
  2. datasource:
  3. serviceDB:
  4. jdbc-url: jdbc:mysql://127.0.0.1:3306/serviceDB
  5. password: test
  6. minimum-idle: 1
  7. idle-timeout: 60000
  8. maximum-pool-size: 150
  9. username: root
  10. cluster:
  11. - key: bi
  12. jdbc-url: jdbc:mysql://127.0.0.1:3306/test
  13. password: test
  14. minimum-idle: 1
  15. idle-timeout: 60000
  16. maximum-pool-size: 150
  17. username: root
  18. - key: his
  19. jdbc-url: jdbc:mysql://127.0.0.1:3306/his
  20. password: test
  21. minimum-idle: 1
  22. idle-timeout: 60000
  23. maximum-pool-size: 150
  24. username: root
  25. config:
  26. schedul:
  27. onOff: false
  28. orderGen:
  29. masterWorkerId: 1
  30. backupWorkerId: 2

解析得到的结果如下所示:

  1. {
  2. "spring.datasource.serviceDB.jdbc-url": "jdbc:mysql://127.0.0.1:3306/serviceDB",
  3. "spring.datasource.serviceDB.password": "test",
  4. "spring.datasource.serviceDB.username": "root",
  5. "spring.datasource.cluster[0].key": "bi",
  6. "spring.datasource.cluster[1].maximum-pool-size": "150",
  7. "config.schedul.onOff": "false",
  8. "spring.datasource.cluster[0].password": "test",
  9. "spring.datasource.cluster[0].maximum-pool-size": "150",
  10. "spring.datasource.cluster[1].username": "root",
  11. "spring.datasource.serviceDB.idle-timeout": "60000",
  12. "config.orderGen.backupWorkerId": "2",
  13. "spring.datasource.cluster[1].idle-timeout": "60000",
  14. "spring.datasource.serviceDB.minimum-idle": "1",
  15. "spring.datasource.cluster[0].username": "root",
  16. "spring.datasource.cluster[1].key": "his",
  17. "config.orderGen.masterWorkerId": "1",
  18. "spring.datasource.cluster[0].minimum-idle": "1",
  19. "spring.datasource.cluster[0].idle-timeout": "60000",
  20. "spring.datasource.cluster[1].password": "test",
  21. "spring.datasource.cluster[0].jdbc-url": "jdbc:mysql://127.0.0.1:3306/test",
  22. "spring.datasource.serviceDB.maximum-pool-size": "150",
  23. "spring.datasource.cluster[1].minimum-idle": "1",
  24. "spring.datasource.cluster[1].jdbc-url": "jdbc:mysql://127.0.0.1:3306/his"
  25. }

实现思路

第一步:使用yml读取文件

  1. Yaml yaml = new Yaml();
  2. Map<String, Object> testMap =
  3. yaml.load( new BufferedReader(new FileReader("test.yml")));

但是此时得到的testMap不是我们想要的结果,testMap的内容如下:

{"spring":{"datasource":{"serviceDB":{"jdbc-url":"jdbc:mysql://127.0.0.1:3306/serviceDB","password":"test","minimum-idle":1,"idle-timeout":60000,"maximum-pool-size":150,"username":"root"},"cluster":[{"key":"bi","jdbc-url":"jdbc:mysql://127.0.0.1:3306/test","password":"test","minimum-idle":1,"idle-timeout":60000,"maximum-pool-size":150,"username":"root"},{"key":"his","jdbc-url":"jdbc:mysql://127.0.0.1:3306/his","password":"test","minimum-idle":1,"idle-timeout":60000,"maximum-pool-size":150,"username":"root"}]}},"config":{"schedul":{"onOff":false},"orderGen":{"masterWorkerId":1,"backupWorkerId":2}}}

第二步:得到testMap后需要进行进一步的解析,得到需要的结果,这个时候就要使用递归解析了,需要注意的是对于yml中数组的解析要重点处理

核心代码如下:

  1. /**
  2. *
  3. * @Title: json2propMap
  4. * @Description: 解析json 转换 Map
  5. * @param jsonObject
  6. * @return
  7. * @throws
  8. *
  9. */
  10. public static Map<String, Object> json2propMap(JSONObject jsonObject){
  11. String tmpKey = "";
  12. String tmpKeyPre = "";
  13. Map<String, Object> configMap = new HashMap<String, Object>();
  14. json2prop(jsonObject, tmpKey, tmpKeyPre, configMap);
  15. return configMap;
  16. }
  17. /**
  18. *
  19. * @Title: json2prop
  20. * @Description: 递归解析
  21. * @param jsonObject
  22. * @param tmpKey
  23. * @param tmpKeyPre
  24. * @param configMap
  25. * @throws
  26. *
  27. */
  28. private static void json2prop(JSONObject jsonObject, String tmpKey, String tmpKeyPre, Map<String, Object> configMap) {
  29. Iterator<String> iterator = jsonObject.keySet().iterator();
  30. while (iterator.hasNext()) {
  31. // 获得key
  32. String key = iterator.next();
  33. String value = jsonObject.getString(key);
  34. Object valueObject = null;
  35. try {
  36. valueObject = JSONObject.parse(value);
  37. } catch (Exception e) {
  38. // 如果解析出错,就说明已经到头了,放入map然后继续解析
  39. configMap.put(tmpKey + key, value);
  40. continue;
  41. }
  42. // 如果是集合,需要特殊解析
  43. if (valueObject instanceof Collection<?>) {
  44. List<?> list = (List<?>)valueObject;
  45. tmpKeyPre = tmpKey;
  46. // tmpKey += key;
  47. for (int i = 0; i < list.size(); i++) {
  48. String itemKey = tmpKey + key + "["+i+"]" + ".";
  49. JSONObject itemValue = (JSONObject)list.get(i);
  50. json2prop(itemValue, itemKey, tmpKeyPre, configMap);
  51. }
  52. } else if (valueObject instanceof JSONObject) {
  53. JSONObject jsonStr = JSONObject.parseObject(value);
  54. tmpKeyPre = tmpKey;
  55. tmpKey += key + ".";
  56. json2prop(jsonStr, tmpKey, tmpKeyPre, configMap);
  57. tmpKey = tmpKeyPre;
  58. } else {
  59. configMap.put(tmpKey + key, value);
  60. continue;
  61. }
  62. }
  63. }

第三步:得到最终结果,终极代码如下:

  1. public static void main(String[] args) throws FileNotFoundException {
  2. Yaml yaml = new Yaml();
  3. Map<String, Object> testMap = yaml.load( new BufferedReader(new FileReader("test.yml")));
  4. System.out.println(JsonUtil.toJson(testMap));
  5. JSONObject jsonObject = JSONObject.parseObject(JsonUtil.toJson(testMap));
  6. // 递归解析Map
  7. testMap = JsonUtil.json2propMap(jsonObject);
  8. System.out.println(JsonUtil.toJson(testMap));
  9. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/653719
推荐阅读
相关标签
  

闽ICP备14008679号