springboot 整合freemarker(SpringBoot使用freemarker解析替换文本)
springboot 整合freemarker(SpringBoot使用freemarker解析替换文本)public String sendWxTemplateMsg(TemplateParameterDto parameterDto) { // 发送模板消息接口 WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() // 接收者openid .toUser(parameterDto.getOpenId()) // 模板id .templateId(parameterDto.getTemplateId()) // 模板跳转链接 .url(parameterDto.getUrl())
没有需求,谈什么技术呢?之前有做过微信模版消息推送,今天遇到一个需求,需求方要求内容可以根据传入的字段自由组合,但是并不是毫无规则的组合,而是根据调用方传入的Json数据填充一个业务方自定义的模版。那么其实这个需求并不难,因为借助模版引擎就可以实现。那么接下来我们就进一步探究一下。
在Java中其实也有很多模版引擎,比如:freemarker、thymeleaf、velocity等,这里的选择freemarker作为我们这次的主角,
那么,在开始之前,先简单的了解它的几个基语法:
- 取值:占位符方式${name},对象方式${obj.name}
- 判断:<#if vo.CUSTCODE ?exists ></#if>
- 比较:<#if vo.CUSTCODE ?exists || vo.PHONE ?length gt 0></#if>
- 运算符:${num num1} ${num-num1}
在开始之前,我们需要先引入jar包:
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
好了,继续我们今天的主题。来,先举个例子,下面是我的微信模版配置
模版key替换内容first该订单信息${orderNo} 共支付${money}keyword1${orderNo}keyword2${orderTime}keyword3${money}keyword4${pay}remark说明${orderNo} 通过${pay}支付了${money}假如我的请求参数是
{
"orderNo": "5555555"
"money": "8888888"
"orderTime":"2020-09-03 15:46:56"
"pay":"支付宝"
}
这里我们就借助freemarker来解析我们的模版
Map<String String> template = new HashMap<String String>() {{
put("first" "该订单信息${orderNo} 共支付${money} ");
put("keyword1" "${orderNo}");
put("keyword2" "${orderTime}");
put("keyword3" "${money}");
put("keyword4" "${pay}");
put("remark" "说明${orderNo} 通过${pay}支付了${money} ");
}};
List<WxMpTemplateData> wxMpTemplateData = new ArrayList<>(template.size());
JSONObject jsonObject= JSON.parseObject("{\n"
" \"orderNo\": \"5555555\" \n"
" \"money\": \"8888888\" \n"
" \"orderTime\":\"2020-09-03 15:46:56\" \n"
" \"pay\":\"支付宝\"\n"
" }");
template.forEach((key value) -> {
try {
Template tpl = new Template(null value null);
Writer out = new StringWriter(2048);
tpl.process(jsonObject out);
wxMpTemplateData.add(new WxMpTemplateData(key out.toString()));
} catch (IOException | TemplateException e) {
e.printStackTrace();
}
});
TemplateParameterDto parameterDto=new TemplateParameterDto();
parameterDto.setAppId("wxb677b1efd92ade95");
parameterDto.setOpenId("oEd4cw2JNl-l_d7_RKnPzKyI-M7U");
parameterDto.setTemplateId("suUhCCo9owmD8QYbdcSgmG3uXwPsDE1Wn8eKThztS7U");
parameterDto.setUrl("https://www.baidu.com");
parameterDto.setTemplateDataList(wxMpTemplateData);
log.info("模版内容:[{}]" JSON.toJSONString(wxMpTemplateData));
pushService.sendWxTemplateMsg(parameterDto);
sendWxTemplateMsg方法的逻辑在之前的文章中稍微作了一些调整
public String sendWxTemplateMsg(TemplateParameterDto parameterDto) {
// 发送模板消息接口
WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
// 接收者openid
.toUser(parameterDto.getOpenId())
// 模板id
.templateId(parameterDto.getTemplateId())
// 模板跳转链接
.url(parameterDto.getUrl())
.build();
// 添加模板数据
templateMessage.setData(parameterDto.getTemplateDataList());
String msgId = null;
try {
//根据appId切换公众号
wxMpService.switchover(parameterDto.getAppId());
// 发送模板消息
msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
} catch (WxErrorException e) {
e.printStackTrace();
}
return msgId;
}
解析后的模版内容如下:
模版内容:[[{"name":"keyword3" "value":"8888888"} {"name":"keyword4" "value":"支付宝"} {"name":"keyword1" "value":"5555555"} {"name":"keyword2" "value":"2020-09-03 15:46:56"} {"name":"remark" "value":"说明5555555 通过支付宝支付了8888888 "} {"name":"first" "value":"该订单信息5555555 共支付8888888 "}]]
刚才用freemarker填充了简单的模版,其实它还可以完成更加复杂的对象,我们来举个栗子
Map<String String> template = new HashMap<String String>() {{
put("first" "${ext.greet} ${ext.name}");
put("keyword1" "${orderNo}");
put("keyword2" "${orderTime}");
put("keyword3" "${money}");
put("keyword4" "${pay}");
put("remark" "说明${orderNo} 通过${pay}支付了${money} ${ext.memo} ");
}};
List<WxMpTemplateData> wxMpTemplateData = new ArrayList<>(template.size());
JSONObject jsonObject= JSON.parseObject("{\n"
" \"orderNo\": \"5555555\" \n"
" \"money\": \"8888888\" \n"
" \"orderTime\": \"2020-09-03 15:46:56\" \n"
" \"pay\": \"支付宝\" \n"
" \"ext\": {\n"
" \"greet\": \"你好\" \n"
" \"name\": \"靓大叔\" \n"
" \"memo\": \"大兄弟,感谢你的支持\"\n"
" }\n"
" }");
最后解析出来的结果是这样子的
[[{"name":"keyword3" "value":"8888888"} {"name":"keyword4" "value":"支付宝"} {"name":"keyword1" "value":"5555555"} {"name":"keyword2" "value":"2020-09-03 15:46:56"} {"name":"remark" "value":"说明5555555 通过支付宝支付了8888888 大兄弟,感谢你的支持 "} {"name":"first" "value":"你好 靓大叔"}]]
freemarker还支持一些复杂的表达等,这里暂时用不上,就不继续探究了。因为业务是想尽量将控制放在我们这里,而不是调用方,所以才行想这样的方式来处理。
我只是记录我的学习过程,由于书读得少,可能很多地方表述或者是理解得不对,请轻喷并指正。