详解java如何实现将数据导出为yaml
需求描述
需求:根据用户在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
技术调研
这里直接给结论,关于下面提及的技术在网上资料很多,我也会把我参考的资料贴在文章尾部。
简单介绍一下这里提及的两个技术:
- snakeyaml: 支持javabean转为yaml文件,也支持读取yaml文件为javabean对象。类似fastjson可以实现javabean与json相互转化。
- freemark:比较成熟的template engine之一。
1.采用snakeyaml
优点:生成yaml文件简单,有相应的api可直接调用。只要把封装数据传给snakeyaml即可
缺点:
- 和需求文档中的变量顺序不一致,生成的按照字母顺序排序;注释不好处理 。
- java对象属性名需要和yaml中的一致。但是yaml中采用大写加下划线的风格、java中变量名采用驼峰命名风格。(初步尝试了做变量风格转换,要继承snakeyaml的一些类重写部分函数,比较复杂。而且后面要读取yaml文档时,又要做一次逆向风格替换。)
2.采用freemarker
优点:
- 以按照需求文档中的配置项顺序生成yaml文件
- 变量名风格可以不一致
缺点:
- 需要自己写yaml语法规则
- 如果变量名风格不一致,在读取yaml文件时会增加复杂度
3.snakeyaml + freemarker
优点:
- 可以按照需求文档中的配置项顺序生成yaml文件
- 生成yaml文件逻辑较为简单
缺点:
- 需求文档中使用块序列风格,这种方式将以流序列风格生成文档
- 如果变量名风格不一致,在读取yaml文件时会增加复杂度
调研反馈
和产品沟通后,第三种方式提到的两个缺点不是问题。
结论:1.读取yaml文件功能不需要开发(是我多虑了,哈哈);2.块序列风格转为流序列风格。
理论落地
snakeyaml + freemarker的实现思路是:根据需求中的yaml文件提取出一个模板,然后通过数据填充的方式,给模板填充使用snakeyaml预处理过的数据,如此即可生成一份令产品满意的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/"); } /** * 根据模板生成单个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转储辅助类
由于业务特殊,源码就不贴了。这个类具体怎么写根据大家自己的业务逻辑,它的作用是利用snakeyaml对数据进行预处理,把数据转换成yaml的流序列格式。
//示例: DumperOptions dumperOptions = new DumperOptions(); // 指定流序列格式 dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW); Yaml settingDumper = new Yaml(dumperOptions); // 把数据转换成yaml的流序列格式。 public String getFlags() { return settingDumper.dump(settingBO.getFlags()); }
step 4:利用工具类生成yaml文件
YamlGeneratorUtil.generate("config.ftl", your_output_file, your_dump_helper);
到此这篇关于详解java如何实现将数据导出为yaml的文章就介绍到这了,更多相关java数据导出为yaml内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
SpringBoot中HttpSessionListener的简单使用方式
这篇文章主要介绍了SpringBoot中HttpSessionListener的简单使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-03-03SecurityUtils.getSubject().getPrincipal()为null的问题
这篇文章主要介绍了SecurityUtils.getSubject().getPrincipal()为null的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-07-07springboot项目启动的时候,运行main方法报错NoClassDefFoundError问题
这篇文章主要介绍了springboot项目启动的时候,运行main方法报错NoClassDefFoundError问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-01-01
最新评论