这个功能可能我题目中的叙述有点问题。重新解释一下,我们众所周知的微信小程序和app大不相同,最大的区别是app可以独立进行消息推送,而微信小程序却不行,也就是这个原因,所以小程序中如果想做什么提醒用户的操作,只能走订阅推送了。大概的步骤就是小程序授权允许消息推送(反正就这个意思,是不是叫推送我不记得了),然后这样当有需要的时候可以把消息发送到微信的服务通知里,正常来讲类似于微信收到了一条新消息的那种模式。
然后java代码的实现也比较简单,主要是配置什么的要符合微信小程序后台的配置,需要注意的是这个需要获取的参数有小程序的accessToken和小程序中用户的openId,当然了还有模板消息和消息实体对象之类的。
所以我这里会写的比较长,openId的话应该是存储在小程序用户的用户信息表里的,所以这里不多叙述,但是accessToken的话我这里是每次都去获取,所以专门封装了个方法(小程序开发本身的appId和秘钥就不说了)。
获取accessToken:
static String appid = "你的appId";
static String secret = "你的secret";
public static String getAccessToken() throws Exception {
String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid
+ "&secret=" + secret;
URL url = new URL(requestUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
// 设置通用的请求属性
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setDoInput(true);
// 得到请求的输出流对象
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("");
out.flush();
out.close();
// 建立实际的连接
connection.connect();
// 定义 BufferedReader输入流来读取URL的响应
BufferedReader in = null;
if (requestUrl.contains("nlp"))
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "GBK"));
else
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String result = "";
String getLine;
while ((getLine = in.readLine()) != null) {
result += getLine;
}
in.close();
JSONObject jsonObject = JSON.parseObject(result);
String accesstoken = jsonObject.getString("access_token");
System.out.println(accesstoken);
return accesstoken;
}
如上,是一个提炼的很好的获取accessToken的方法,返回值也经过处理只返回accessToken。
因为openId应该是存储在用户表里,所以这里不多叙说,模板id也应该在配置那里获取到了,所以也可以用静态常量表示。
发送小心代码实现
这里有两个是数据封装的实体:
/**
* 订阅消息
* @author lisijia
* @email 1151141449@qq.com
* @date 2020/7/7 10:57
*/
public class SubscribeMessage {
//接口调用凭证
private String access_token;
//接收者(用户)的 openid
private String touser;
//所需下发的订阅模板id
private String template_id;
//点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
private String page;
//模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }
private Map<String, TemplateData> data;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getTouser() {
return touser;
}
public void setTouser(String touser) {
this.touser = touser;
}
public String getTemplate_id() {
return template_id;
}
public void setTemplate_id(String template_id) {
this.template_id = template_id;
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
public Map<String, TemplateData> getData() {
return data;
}
public void setData(Map<String, TemplateData> data) {
this.data = data;
}
}
/**
* @author lisijia
* @email 1151141449@qq.com
* @date 2020/7/7 10:58
*/
public class TemplateData {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public TemplateData(String value) {
this.value = value;
}
}
然后是发送订阅消息的方法(其实这里是分两步的,一步是单纯的触发发送订阅消息,还有一部分是参数的命名及写法):
public static void subscribeMessage(String openId, String page, Map<String, TemplateData> map) {
try {
String accessToken = getAccessToken();
SubscribeMessage subscribeMessage = new SubscribeMessage();
// 拼接数据
subscribeMessage.setAccess_token(accessToken);
subscribeMessage.setTouser(openId);
subscribeMessage.setTemplate_id(templateId);//事先定义好的模板id
subscribeMessage.setPage(page);
subscribeMessage.setData(map);
String json = JSONObject.toJSONString(subscribeMessage);
JsonNode ret = null;
ret = Unirest.post("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken)
.body(json).asJson().getBody();
System.out.println(ret);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Map<String, TemplateData> map = new HashMap<>();
map.put("date4", new TemplateData(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())));
map.put("thing12", new TemplateData("温度过高"));
map.put("thing1", new TemplateData("氙灯老化试验箱"));
map.put("thing2", new TemplateData("BJYSL-SN-500"));
map.put("thing3", new TemplateData("实验箱温度"));
subscribeMessage("oPUD35dzUstVi8VDqMQOW1P6EElY", "", map);
}
注意一下,这里的什么date4.thing12,thing2之类的都是模板自动生成的,一定key名称要对应上。还有thing是有长度限制的,好像是20字符。
然后page参数我这里没传,说实话我也不清楚是干啥的,反正之前我看的demo里就是空。
至于这个openId一定是这个小程序下生成的openId属于常识,我顺口也就提一下。
这个我认为比较好的一点是报错信息写的非常明确,我之前遇到的几个问题都是一看报错信息就找到原因了,然后直接运行main方法打印如下说明发送成功了:
模板消息发送成功
本篇笔记就记到这里,如果稍微帮到你了记得点个喜欢点个关注,也祝大家工作顺顺利利!java技术交流群130031711,欢迎各位的加入!
网友评论