詳解java如何實現(xiàn)將數(shù)據(jù)導出為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)上資料很多,我也會把我參考的資料貼在文章尾部。
簡單介紹一下這里提及的兩個技術(shù):
- snakeyaml: 支持javabean轉(zhuǎn)為yaml文件,也支持讀取yaml文件為javabean對象。類似fastjson可以實現(xiàn)javabean與json相互轉(zhuǎn)化。
- freemark:比較成熟的template engine之一。
1.采用snakeyaml
優(yōu)點:生成yaml文件簡單,有相應(yīng)的api可直接調(diào)用。只要把封裝數(shù)據(jù)傳給snakeyaml即可
缺點:
- 和需求文檔中的變量順序不一致,生成的按照字母順序排序;注釋不好處理 。
- java對象屬性名需要和yaml中的一致。但是yaml中采用大寫加下劃線的風格、java中變量名采用駝峰命名風格。(初步嘗試了做變量風格轉(zhuǎn)換,要繼承snakeyaml的一些類重寫部分函數(shù),比較復(fù)雜。而且后面要讀取yaml文檔時,又要做一次逆向風格替換。)
2.采用freemarker
優(yōu)點:
- 以按照需求文檔中的配置項順序生成yaml文件
- 變量名風格可以不一致
缺點:
- 需要自己寫yaml語法規(guī)則
- 如果變量名風格不一致,在讀取yaml文件時會增加復(fù)雜度
3.snakeyaml + freemarker
優(yōu)點:
- 可以按照需求文檔中的配置項順序生成yaml文件
- 生成yaml文件邏輯較為簡單
缺點:
- 需求文檔中使用塊序列風格,這種方式將以流序列風格生成文檔
- 如果變量名風格不一致,在讀取yaml文件時會增加復(fù)雜度
調(diào)研反饋
和產(chǎn)品溝通后,第三種方式提到的兩個缺點不是問題。
結(jié)論:1.讀取yaml文件功能不需要開發(fā)(是我多慮了,哈哈);2.塊序列風格轉(zhuǎn)為流序列風格。
理論落地
snakeyaml + freemarker的實現(xiàn)思路是:根據(jù)需求中的yaml文件提取出一個模板,然后通過數(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ù)模板生成單個yaml配置文件 * @param templateName 模板名稱 * @param outputFileName 生成的文件名 * @param settingDumpHelper 配置轉(zhuǎn)儲輔助類 */ 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)儲輔助類
由于業(yè)務(wù)特殊,源碼就不貼了。這個類具體怎么寫根據(jù)大家自己的業(yè)務(wù)邏輯,它的作用是利用snakeyaml對數(shù)據(jù)進行預(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如何實現(xiàn)將數(shù)據(jù)導出為yaml的文章就介紹到這了,更多相關(guān)java數(shù)據(jù)導出為yaml內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用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é)合的方式給大家講解的非常詳細,需要的朋友可以參考下2024-05-05淺談Java中Int、Integer、Integer.valueOf()、new Integer()之間的區(qū)別
本文主要介紹了淺談Java中Int、Integer、Integer.valueOf()、new Integer()之間的區(qū)別,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11深入研究spring boot集成kafka之spring-kafka底層原理
這篇文章主要深入研究了spring boot集成kafka如何實現(xiàn)spring-kafka的底層原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步2022-02-02