JFinal使用技巧-Enjoy巧用在微信公众号消息通知上

最近没有来社区分享东西了,响应波总创业号召回西安创业了~,技术学习懈怠了。。。组建小团队,忙活各种项目累够呛。。。言归正传,上石马!

昨天有个需求,就是微信消息通知 支持跳小程序某页面。
微信文档中给出例子:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html

//PS:这个官网例子有坑,不要只看这一句,注意后面的是正确使用的
{
           "touser":"OPENID",
           "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
           "url":"http://weixin.qq.com/download",  
           "miniprogram":{
             "appid":"xiaochengxuappid12345",
             "pagepath":"index?foo=bar"
           },          
           "data":{
                   "first": {
                       "value":"恭喜你购买成功!",
                       "color":"#173177"
                   },
                   "keyword1":{
                       "value":"巧克力",
                       "color":"#173177"
                   },
                   "keyword2": {
                       "value":"39.8元",
                       "color":"#173177"
                   },
                   "keyword3": {
                       "value":"2014年9月22日",
                       "color":"#173177"
                   },
                   "remark":{
                       "value":"欢迎再次购买!",
                       "color":"#173177"
                   }
           }
       }

就是增加miniprogram参数,看着很简单啊,但是没有发送出去啊。 去掉miniprogram就能发出去了,检查appid和路径都已经进行管理公众号了,那问题一定就是出现在参数上了。 我们挨个排除, 发现文档中说的pagepath 需要改成 pagepaths 加一个S就能正常发送,然后又发现路径上携带的参数没有被正常挂入,检查发现我们小程序项目是有pages和模块名划分 文件夹 的,被它这个实例给坑了一下。。。

我们正常能发送的例子写法是:

{
           "touser":"OPENID",
           "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
           "url":"http://weixin.qq.com/download",  
           "miniprogram":{
             "appid":"xiaochengxuappid12345",
             "pagepaths":"pages/index/index?foo=bar"
           },        
           "data":{
                   "first": {
                       "value":"恭喜你购买成功!",
                       "color":"#173177"
                   },
                   "keyword1":{
                       "value":"巧克力",
                       "color":"#173177"
                   },
                   "keyword2": {
                       "value":"39.8元",
                       "color":"#173177"
                   },
                   "keyword3": {
                       "value":"2014年9月22日",
                       "color":"#173177"
                   },
                   "remark":{
                       "value":"欢迎再次购买!",
                       "color":"#173177"
                   }
           }
       }


好了,微信的梗说了。
那这个Enjoy怎么巧用在微信消息模板上了?
TemplateData这个类大家都会使用,有时候特别是有些需求消息模板文案经常变更的情况下它就没有那么方便了。
其实很简单,JSON其实就是一个字符串嘛! 字符串拼接都能用Enjoy处理~

大致就是这样一个类, 我们对这个类还有很多业务增强,比如传入用户ID,自动查找对应的openid集合等等业务操作:

public class WxMsgKit {

	public ApiResult send(Kv kv){
	        //这里是示例写法,可以使用自己的Engine对象
		String jsonStr = Engine.use().getTemplate("/weixin/msg.jf").renderToString(kv);
		ApiResult send = TemplateMsgApi.send(jsonStr);
		return send;
	}
	
}

然后模板中大致就是这样写的 :

#call(key)

###消息模板a
#define a()
	#--
	绑定提醒
	{{first.DATA}}
	对方帐号:{{keyword1.DATA}}
	绑定状态:{{keyword2.DATA}}
	{{remark.DATA}}
	--#
	{
	       "touser":"#(openid)",
	       "template_id":"xxxx",
	       "url":"xxxx",
	       "topcolor":"#FF0000",
	       "miniprogram":{
	         "appid":"xxxx",
	         "pagepaths":"pages/login/login?jwName=#(jwName)&jwPassword=#(jwPassword)"
	       },
	       "data":{
	               "first": {
	                   "value":"#(accountName), 您好,请点击进入小程序",
	                   "color":"#173177"
	               },
	               "keyword1": {
	                   "value":"#(jwName)",
	                   "color":"#173177"
	               },
	               "keyword2":{
	                   "value":"待绑定",
	                   "color":"#173177"
	               },
	               "remark":{
	                   "value":"点击进入小程序",
	                   "color":"#FF0000"
	               }
	       }
	}
#end

###消息模板b
#define b()
xxx
#end

渲染json时如果"#(name)" name中有双引号会破坏了json 结构,有需要时,
注意使用替换双引号#(name.replace('"', '\"')??)
或增加模板公共处理函数处理#(EscapeKit.escapeJSON(name)) @chcode 提供:
https://jfinal.com/doc/6-8

public class EscapeKit {
public static String escapeJSON(String text) {
if (text == null) {
return null;
}
int len = text.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char ch = text.charAt(i);
switch (ch) {
case '"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
case '\b':
sb.append("\\b");
break;
case '\f':
sb.append("\\f");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
default:
sb.append(ch);
}
}
return sb.toString();
}
}


调用就不用说了

WxMsgKit.send(Kv.by("key", "a").set("openid", openid)) 如果再对业务数据封装一下,调用就更简洁了

对了, 如果想修改模板后 ,立刻生效记得配置 engine.setDevMode(true);https://www.jfinal.com/doc/6-2


分享完了,又水一篇~ 路过记得顺便点个赞~

评论区

enderjo

2020-04-21 09:56

谢谢分享,已将该思路用于实际项目中。

杜福忠

2020-04-21 10:10

@JFinal 还是enjoy妙不可言!用极少代码实现牛掰的各种功能!谁用谁知道~

杜福忠

2020-04-21 10:14

@enderjo 那太好了,能被运用是分享内容的快乐源泉~

JFinal

2020-04-21 11:04

@杜福忠 在 java 代码层面,传入一个 Kv 对象,里头放一些需要用到的参数,然后在模板中通过 #set(...) 或者调用 kv 传递过来的对象,就可以在 java 与 template 之间传递数据了,包括传回返回值

杜福忠

2020-04-21 11:09

@JFinal 是的,Enjoy SQL 模板SqlPara就是最棒的例子

INFECTION_K

2020-04-21 23:15

我都用来生成XML报文 调接口用 XML报文 200多行。。。 不用enjoy的拼死

JFinal

2020-04-21 23:47

@INFECTION_K 使用 enjoy 生成 XML 是非常合适的场景

有些人用的 String 拼接,很容易出错,代码可读性差。有些人用操作 XML 的那套 API 生成 XML,比 String 拼接还要惨

SuperEric

2020-04-22 10:03

我最近用来生成word文档也是妙不可言,将word转成xml,然后直接在xml中写入enjoy代码..输出直接生成doc.没几行代码.和那个生成html代码基本一样.

杜福忠

2020-04-22 10:08

chcode

2021-12-16 14:37

@杜福忠 看到你这个分享我也这么干了,但是渲染json时如果"#(name)" name中有双引号直接破坏了json 结构 导致了问题,坑了....

杜福忠

2021-12-16 15:43

@chcode 确实有这个问题,如果项目里面没有做限制的话(我们表单录入数据时限制了单双引号)。你这里就得转义一下了,或者增加一个模板公共函数方便使用。我增加一个说明,防止后面有人也坑到

chcode

2022-03-11 15:14

@杜福忠 我增加一个工具类来解决这个问题
public class EscapeKit {
public static String escapeJSON(String text) {
if (text == null) {
return null;
}
int len = text.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char ch = text.charAt(i);
switch (ch) {
case '"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
case '\b':
sb.append("\\b");
break;
case '\f':
sb.append("\\f");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
default:
sb.append(ch);
}
}
return sb.toString();
}
}

杜福忠

2022-03-11 16:53

@chcode 妙哇!解决各种特殊符号,我把代码贴上去

热门分享

扫码入社