Handlebars.java学习笔记 ゞ 浴缸里的玫瑰 2023-01-04 13:25 126阅读 0赞 ## 背景 ## 最近在做一个移动收银的项目,需要使用到银行的设备进行收银。由于使用的是银行设备,每次更新APP是都需要经过银行审核才能上线,这就加大了应用上线的复杂度。而且银行的pos机,性能也有限,通过http请求访问web页面会比较缓慢,会影响收银等操作,影响用户体验。 对于一个新项目来说,在没有经过长时间试运行之前,积累不够,稳定性肯定有所欠缺,基本都需要不断的迭代更新,不断的完善系统交互。估而老大希望将可以预见经常变化的页面的开发工作后置到服务端,避免频繁发布app。如小票打印,由后端生成好最终的打印模板并且输出,app在接收到模板后直接渲染打印,这样如果模板有变化也只需要发布服务端就好,不需要走app的上架流程。 ## Freemarker ## 页面模板化,我第一个想到的是Java模板引擎Freemarker。 > FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。 Freemarker可以将表现层和业务逻辑层代码完全分开,提高代码的可读性;同时能使得开发过程中的人员分工更加明确,实现前后端分离。 Freemarker实现前端页面热部署设计可以参考下图。Freemarker的技术文档网上特别丰富,本文不多做描述。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Fvc2VtYXlp_size_16_color_FFFFFF_t_70] ## Handlebars.java ## 移动收银系统只需要将部分页面模板化,直接使用Freemarker感觉有点大材小用,也相对复杂。在老大的推荐下了解到了Handlebars.java。 > Handlebars 是一种简单的 模板语言,相对于Freemarker更为简单。 > 它使用模板和输入对象来生成 HTML 或其他文本格式。Handlebars 模板看起来像常规的文本,但是它带有嵌入式的 Handlebars 表达式 。 ### 基础用法 ### 1、表达式是一些以双花括号 \{ \{\}\} 括起来的内容; 2、在 Handlebars 中, \{ \{expression\}\} 返回的值是 HTML 转义的。如果一个表达式的内容包含 &等HTML特殊字符时,Handlebars会自动转义。如果你不希望 Handlebars 转义字符的话,可以 修改为\{ \{ \{expression\}\}\}; 3、Handlebars的入参可以是任何类型,String、Map、自定义对象; 4、Handlebars的模板可以是一个hbs、html等格式的文件,也可以是一个字符串。 #### if助手 #### { { #if condition}} ... { { /if}} #### for循环表达式(each助手) #### { { #each list}} ... { { /each}} #### 代码实现 #### ##### maven ##### <dependency> <groupId>com.github.jknack</groupId> <artifactId>handlebars</artifactId> <version>4.2.0</version> </dependency> ##### 加载解析模板------文件 ##### private final static String LOCAL_ROOT_PATH = "/"; private final static String TEMPLATE_PREFIX = "/templates"; public static String compile(String templateName,Object var1){ TemplateLoader loader = new FileTemplateLoader(new File(LOCAL_ROOT_PATH)); loader.setPrefix(TEMPLATE_PREFIX); Handlebars handlebars = new Handlebars(loader); try { Template template = handlebars.compile(templateName); return template.apply(var1); } catch (Exception e) { LOGGER.warn(LogEvent.of(HANDLEBARS_LOG_EVENT,"handlebars 封装模板异常 message : {} , e : {}",e.getLocalizedMessage(),e)); } return null; } ##### 加载解析模板------字符串 ##### 字符串形式更为便捷,可以丢到redis中,能提升性能,更新也更为方便 public static String compileInline(String templateName,Object var1){ String key = VposRedisConstant.VPOS_HANDLEBARS_KEY + templateName; String templateString = getTemplateString(key,templateName); if(StringUtils.isEmpty(templateString)){ return null; } Handlebars handlebars = new Handlebars(); try { Template template = handlebars.compileInline(templateString); return template.apply(var1); } catch (Exception e) { LOGGER.warn(LogEvent.of(HANDLEBARS_LOG_EVENT,"handlebars 封装模板异常 message : {} , e : {}",e.getLocalizedMessage(),e)); } return null; } private static String getTemplateString(String key,String templateName){ String templateString = RedisUtil.getInstance().getString(key); if(StringUtils.isNotEmpty(templateString)){ return templateString; } File template = FileUtil .downloadFile(TEMPLATES_PATH, templateName + TEMPLATE_SUFFIX_HBS, TEMPLATE_TEMPORARY_PATH); templateString = FileUtils.readFileToString(template, "utf-8"); if(StringUtils.isNotEmpty(templateString)){ FcsVposRedisUtil.getInstance().set(key,templateString,36000); } return templateString; } ##### 入参 ##### String template = HandlebarsUtils.compileInline("sale.hbs",orderTemplate); @Getter @Setter @AllArgsConstructor @NoArgsConstructor public class OrderTemplate { private List<PayModel> PayModels; private String totalPayAmount; private double orderGoodsMoney; private double orderDiscount; } @Getter @Setter @AllArgsConstructor @NoArgsConstructor public class PayModel{ private String payMethod; private String payMethodName; private String amount; } ##### 模板样例 ##### <div class="diary-detail-h5"> <div class="d-flex flex-row justify-content-start align-items-center flex-wrapper"> <div class="d-flex flex-row flex-fill justify-content-start align-items-start flex-demo"> <p class="p-justify vpos-diary-bold">销售商品总金额:</p></div> <div class="d-flex flex-row flex-fill justify-content-end align-items-start flex-demo"> <p class="vpos-diary-bold">¥{ { orderGoodsMoney}}</p></div> </div> { { #if orderDiscount '!=' null}} <div class="d-flex flex-row justify-content-start align-items-center flex-wrapper"> <div class="d-flex flex-row flex-fill justify-content-start align-items-start flex-demo"> <p class="p-justify vpos-diary-bold">销售优惠合计:</p></div> <div class="d-flex flex-row flex-fill justify-content-end align-items-start flex-demo"> <p class="vpos-diary-bold">¥{ { orderDiscount}}</p></div> </div> { { /if}} <div class="vpos-diary-comp"> <p class="vpos-diary-bold vpos-detail-title">收款明细</p> <div class="vpos-day-dummary-line-list"> { { #each PayModels}} <div class="d-flex flex-row justify-content-start align-items-center flex-wrapper"> <div class="d-flex flex-row flex-fill justify-content-start align-items-start flex-demo"> <p class="p-justify">{ { payMethodName}}:</p></div> <div class="d-flex flex-row flex-fill justify-content-end align-items-start flex-demo"> <p>¥{ { amount}}</p> </div> </div> { { /each}} <div class="d-flex flex-row justify-content-start align-items-center flex-wrapper"> <div class="d-flex flex-row flex-fill justify-content-start align-items-start flex-demo"> <p class="p-justify vpos-diary-bold">收款合计:</p></div> <div class="d-flex flex-row flex-fill justify-content-end align-items-start flex-demo"> <p class="vpos-diary-bold">¥{ { totalPayAmount}}</p></div> </div> </div> </div> </div> # 参考资料 # Handlebars.java还有很多其他用法,如with、unless、helpers等,详情见:https://github.com/jknack/handlebars.java 作者:张伟峰 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Fvc2VtYXlp_size_16_color_FFFFFF_t_70]: /images/20221119/6a297202e1204680a01e821559b8202b.png
相关 「学习笔记」学习笔记合集 可以点击 [https://www.cnblogs.com/hongzy/tag/%E7%AC%94%E8%AE%B0/][https_www.cnblogs.com_hong 淩亂°似流年/ 2023年06月05日 12:48/ 0 赞/ 20 阅读
相关 学习笔记 学习笔记 sudo adduser lilei sudo usermod -G sudo lilei sudo deluse 客官°小女子只卖身不卖艺/ 2022年11月26日 12:58/ 0 赞/ 27 阅读
相关 学习笔记 \ajax: 1、概念:异步的JavaScript 和 xml 1.1异步和同步:客户端和服务器端相互通信的基础上 \客户端必须等待服务器端的响应。在等待的期间客户 深藏阁楼爱情的钟/ 2022年10月29日 13:24/ 0 赞/ 281 阅读
相关 学习笔记 一. CSS 如何实现文字的垂直居中 1. 二.问题记录 1.创建新的JSP页面的时候报错:The superclass “javax.servlet.http.H 超、凢脫俗/ 2022年08月20日 09:30/ 0 赞/ 144 阅读
相关 【学习笔记】git学习笔记 使用git的好处 可以保存每个版本,只要在每个版本做完后进行上传 ![这里写图片描述][70] 可以异地读取更新 爱被打了一巴掌/ 2022年05月14日 09:10/ 0 赞/ 407 阅读
相关 学习笔记 我的第一天学习c\ 1、c\学习网址 [https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide 矫情吗;*/ 2022年05月08日 06:16/ 0 赞/ 326 阅读
相关 学习笔记 测试 ORM JPA EJB JPQL MOM JMS ORM 对象关系映射 英语:Object Relational M 爱被打了一巴掌/ 2022年02月16日 01:57/ 0 赞/ 397 阅读
相关 [笔记] Docker 学习笔记 1. 什么是 Docker > 官方文档:[链接][Link 1],中文文档:[链接][Link 2] Docker 属于 Linux 容器的一种封装,提供简单易用的容 缺乏、安全感/ 2021年11月27日 02:01/ 0 赞/ 592 阅读
相关 学习笔记 1、js如何将136分钟转化为几小时,几分钟 return (Math.floor(minutes/60) + "小时" + (minutes%60) + "分" 爱被打了一巴掌/ 2021年07月25日 23:46/ 0 赞/ 1052 阅读
还没有评论,来说两句吧...