詳解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
技術調(diào)研
這里直接給結論,關于下面提及的技術在網(wǎng)上資料很多,我也會把我參考的資料貼在文章尾部。
簡單介紹一下這里提及的兩個技術:
- snakeyaml: 支持javabean轉為yaml文件,也支持讀取yaml文件為javabean對象。類似fastjson可以實現(xiàn)javabean與json相互轉化。
- freemark:比較成熟的template engine之一。
1.采用snakeyaml
優(yōu)點:生成yaml文件簡單,有相應的api可直接調(diào)用。只要把封裝數(shù)據(jù)傳給snakeyaml即可
缺點:
- 和需求文檔中的變量順序不一致,生成的按照字母順序排序;注釋不好處理 。
- java對象屬性名需要和yaml中的一致。但是yaml中采用大寫加下劃線的風格、java中變量名采用駝峰命名風格。(初步嘗試了做變量風格轉換,要繼承snakeyaml的一些類重寫部分函數(shù),比較復雜。而且后面要讀取yaml文檔時,又要做一次逆向風格替換。)
2.采用freemarker
優(yōu)點:
- 以按照需求文檔中的配置項順序生成yaml文件
- 變量名風格可以不一致
缺點:
- 需要自己寫yaml語法規(guī)則
- 如果變量名風格不一致,在讀取yaml文件時會增加復雜度
3.snakeyaml + freemarker
優(yōu)點:
- 可以按照需求文檔中的配置項順序生成yaml文件
- 生成yaml文件邏輯較為簡單
缺點:
- 需求文檔中使用塊序列風格,這種方式將以流序列風格生成文檔
- 如果變量名風格不一致,在讀取yaml文件時會增加復雜度
調(diào)研反饋
和產(chǎn)品溝通后,第三種方式提到的兩個缺點不是問題。
結論:1.讀取yaml文件功能不需要開發(fā)(是我多慮了,哈哈);2.塊序列風格轉為流序列風格。
理論落地
snakeyaml + freemarker的實現(xiàn)思路是:根據(jù)需求中的yaml文件提取出一個模板,然后通過數(shù)據(jù)填充的方式,給模板填充使用snakeyaml預處理過的數(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 配置轉儲輔助類
*/
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轉儲輔助類
由于業(yè)務特殊,源碼就不貼了。這個類具體怎么寫根據(jù)大家自己的業(yè)務邏輯,它的作用是利用snakeyaml對數(shù)據(jù)進行預處理,把數(shù)據(jù)轉換成yaml的流序列格式。
//示例:
DumperOptions dumperOptions = new DumperOptions();
// 指定流序列格式
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW);
Yaml settingDumper = new Yaml(dumperOptions);
// 把數(shù)據(jù)轉換成yaml的流序列格式。
public String getFlags() {
return settingDumper.dump(settingBO.getFlags());
}
step 4:利用工具類生成yaml文件
YamlGeneratorUtil.generate("config.ftl", your_output_file, your_dump_helper);
到此這篇關于詳解java如何實現(xiàn)將數(shù)據(jù)導出為yaml的文章就介紹到這了,更多相關java數(shù)據(jù)導出為yaml內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java實現(xiàn)京東聯(lián)盟API數(shù)據(jù)獲取功能
這篇文章介紹了Java獲取京東聯(lián)盟API數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07
Java數(shù)據(jù)結構之簡單的連接點(link)實現(xiàn)方法示例
這篇文章主要介紹了Java數(shù)據(jù)結構之簡單的連接點(link)實現(xiàn)方法,涉及java指針指向節(jié)點的相關使用技巧,需要的朋友可以參考下2017-10-10
AQS同步組件CyclicBarrier循環(huán)屏障用例剖析
這篇文章主要為大家介紹了AQS同步組件CyclicBarrier循環(huán)屏障用例剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08
Mybatis批量插入index out of range錯誤的解決(較偏的錯誤)
這篇文章主要介紹了Mybatis批量插入index out of range錯誤的解決(較偏的錯誤),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
springboot中shiro使用自定義注解屏蔽接口鑒權實現(xiàn)
本文主要介紹了springboot中shiro使用自定義注解屏蔽接口鑒權實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07

