詳解java如何實(shí)現(xiàn)將數(shù)據(jù)導(dǎo)出為yaml
需求描述
需求:根據(jù)用戶在web界面勾選的配置生成一份如下格式文檔,保留注釋。
# 我是注釋 VERSION: '1.0' # 我是注釋 FILE_NAME: foo # 我是注釋 UNWIND: COUNT: 3 UNWIND_CHECK: true # 我是注釋 FLAGS: FLAG1: true FLAG2: false FLAG3: true FLAG4: true # 我是注釋 DEFINES: - DEFINE1 - DEFINE2 - DEFINE3
技術(shù)調(diào)研
這里直接給結(jié)論,關(guān)于下面提及的技術(shù)在網(wǎng)上資料很多,我也會(huì)把我參考的資料貼在文章尾部。
簡(jiǎn)單介紹一下這里提及的兩個(gè)技術(shù):
- snakeyaml: 支持javabean轉(zhuǎn)為yaml文件,也支持讀取yaml文件為javabean對(duì)象。類似fastjson可以實(shí)現(xiàn)javabean與json相互轉(zhuǎn)化。
- freemark:比較成熟的template engine之一。
1.采用snakeyaml
優(yōu)點(diǎn):生成yaml文件簡(jiǎn)單,有相應(yīng)的api可直接調(diào)用。只要把封裝數(shù)據(jù)傳給snakeyaml即可
缺點(diǎn):
- 和需求文檔中的變量順序不一致,生成的按照字母順序排序;注釋不好處理 。
- java對(duì)象屬性名需要和yaml中的一致。但是yaml中采用大寫加下劃線的風(fēng)格、java中變量名采用駝峰命名風(fēng)格。(初步嘗試了做變量風(fēng)格轉(zhuǎn)換,要繼承snakeyaml的一些類重寫部分函數(shù),比較復(fù)雜。而且后面要讀取yaml文檔時(shí),又要做一次逆向風(fēng)格替換。)
2.采用freemarker
優(yōu)點(diǎn):
- 以按照需求文檔中的配置項(xiàng)順序生成yaml文件
- 變量名風(fēng)格可以不一致
缺點(diǎn):
- 需要自己寫yaml語法規(guī)則
- 如果變量名風(fēng)格不一致,在讀取yaml文件時(shí)會(huì)增加復(fù)雜度
3.snakeyaml + freemarker
優(yōu)點(diǎn):
- 可以按照需求文檔中的配置項(xiàng)順序生成yaml文件
- 生成yaml文件邏輯較為簡(jiǎn)單
缺點(diǎn):
- 需求文檔中使用塊序列風(fēng)格,這種方式將以流序列風(fēng)格生成文檔
- 如果變量名風(fēng)格不一致,在讀取yaml文件時(shí)會(huì)增加復(fù)雜度
調(diào)研反饋
和產(chǎn)品溝通后,第三種方式提到的兩個(gè)缺點(diǎn)不是問題。
結(jié)論:1.讀取yaml文件功能不需要開發(fā)(是我多慮了,哈哈);2.塊序列風(fēng)格轉(zhuǎn)為流序列風(fēng)格。
理論落地
snakeyaml + freemarker的實(shí)現(xiàn)思路是:根據(jù)需求中的yaml文件提取出一個(gè)模板,然后通過數(shù)據(jù)填充的方式,給模板填充使用snakeyaml預(yù)處理過的數(shù)據(jù),如此即可生成一份令產(chǎn)品滿意的yaml文檔。
step 1:提取freemark模板
# 我是注釋 VERSION: ${dumpHelper.settingBO.version!} # 我是注釋 FILE_NAME: ${dumpHelper.settingBO.fileName!} # 我是注釋 UNWIND: ${dumpHelper.getUnwind()!} # 我是注釋 FLAGS: ${dumpHelper.getFlags()!} # 我是注釋 DEFINES: ${dumpHelper.getDefines()!}
step 2: 編寫生成yaml文件工具類
public class YamlGeneratorUtil { private static final Configuration freemarkerConfig; static { // 初始化Freemarker配置 freemarkerConfig = new Configuration(Configuration.VERSION_2_3_0); freemarkerConfig.setClassForTemplateLoading(YamlGeneratorUtil.class, "/templates/"); } /** * 根據(jù)模板生成單個(gè)yaml配置文件 * @param templateName 模板名稱 * @param outputFileName 生成的文件名 * @param settingDumpHelper 配置轉(zhuǎn)儲(chǔ)輔助類 */ public static void generate(String templateName, String outputFileName, SettingDumpHelper settingDumpHelper) { try (FileWriter fileWriter = new FileWriter(outputFileName)) { Template template = freemarkerConfig.getTemplate(templateName); Map<String, Object> dataModel = new HashMap<>(); dataModel.put("dumpHelper", freemarkerConfig.getObjectWrapper().wrap(settingDumpHelper)); String config = FreeMarkerTemplateUtils.processTemplateIntoString(template, dataModel); fileWriter.write(config); System.out.println(config); } catch (IOException | TemplateException e) { throw new BusinessException(ErrorEnum.build(ErrorEnum.INTERNAL_SERVER_ERROR, "生成yaml文件失敗:" + e.toString())); } } }
step 3:編寫SettingDumpHelper轉(zhuǎn)儲(chǔ)輔助類
由于業(yè)務(wù)特殊,源碼就不貼了。這個(gè)類具體怎么寫根據(jù)大家自己的業(yè)務(wù)邏輯,它的作用是利用snakeyaml對(duì)數(shù)據(jù)進(jìn)行預(yù)處理,把數(shù)據(jù)轉(zhuǎn)換成yaml的流序列格式。
//示例: DumperOptions dumperOptions = new DumperOptions(); // 指定流序列格式 dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW); Yaml settingDumper = new Yaml(dumperOptions); // 把數(shù)據(jù)轉(zhuǎn)換成yaml的流序列格式。 public String getFlags() { return settingDumper.dump(settingBO.getFlags()); }
step 4:利用工具類生成yaml文件
YamlGeneratorUtil.generate("config.ftl", your_output_file, your_dump_helper);
到此這篇關(guān)于詳解java如何實(shí)現(xiàn)將數(shù)據(jù)導(dǎo)出為yaml的文章就介紹到這了,更多相關(guān)java數(shù)據(jù)導(dǎo)出為yaml內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中十進(jìn)制和十六進(jìn)制的相互轉(zhuǎn)換方法
下面小編就為大家?guī)硪黄狫ava中十進(jìn)制和十六進(jìn)制的相互轉(zhuǎn)換方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08使用Eclipse開發(fā)工具如何解決Java Compiler中Annotation Processin不出現(xiàn)的問題
這篇文章主要介紹了使用Eclipse開發(fā)工具如何解決Java Compiler中Annotation Processin不出現(xiàn)的相關(guān)資料,需要的朋友可以參考下2015-11-11IDEA連接MySQL后管理數(shù)據(jù)庫的操作指南
本節(jié)就來教大家如何在IDEA連接MySQL后管理數(shù)據(jù)庫(創(chuàng)建/修改/刪除數(shù)據(jù)庫、創(chuàng)建/修改/刪除表、插入/更新/刪除/查詢表記錄),文中通過圖文結(jié)合的方式給大家講解的非常詳細(xì),需要的朋友可以參考下2024-05-05分析講解SpringMVC注解配置如何實(shí)現(xiàn)
這篇文章主要介紹了本文要介紹用注解方式代替web.xml與SpringMVC的配置文件,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05淺談Java中Int、Integer、Integer.valueOf()、new Integer()之間的區(qū)別
本文主要介紹了淺談Java中Int、Integer、Integer.valueOf()、new Integer()之間的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11深入研究spring boot集成kafka之spring-kafka底層原理
這篇文章主要深入研究了spring boot集成kafka如何實(shí)現(xiàn)spring-kafka的底層原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02