最近听说,小程序的模板消息即将下线,当时正好再做小程序的模板消息这一块,于是乎,去研究了一下小程序的订阅消息。今天就和大家分享一下,我做订阅消息的一些经验,希望能帮助到大家。注:后端用的SpringBoot。
前提:小程序上线需要准备一个https 安全认证的域名,才能访问自己定义的java接口。当然开发的时候,微信开发者工具为我们提供了一个便捷的功能,
把它勾选上,就可以自由的进行访问了。
准备工作:
1.登录自己申请小程序的微信公众平台,记录小程序的AppID和AppSecret
这里的AppSecret如果的话,就自当生成一个。
2.然后申请一个订阅消息的模板,在这里我就不申请,直接用他们提供给的一些模板。
这里需要记录订阅消息的模板ID,便于发送指定的模板消息给用户。还有就是订阅消息的详情,我们接着看
记录好这些之后,我们就可以开始敲代码了。
我们先开始写Java代码
给大家看下我的Java的目录结构
下面我将java代码贴出来给大家
WxController.java(主要是用来获取用户的openid,以及触发模板消息)
package com.buyixs.demo.controller;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import static com.buyixs.demo.utils.WxgzhUtil.httpsRequest;
import static com.buyixs.demo.utils.WxgzhUtil.sendMessageUtils;
@Controller
@RequestMapping ("/wxController")
public class WxController {
@ResponseBody
@RequestMapping("/getUserInfo")
public String getUserInfo(@RequestParam String code){
//获取用户的openid
String appid="";//这里填写自己的appid和secret
String secret="";//这里填写自己的appid和secret
String requestUrl = "https://api.weixin.qq.com/sns/jscode2session?appid="+appid+"&secret="+secret+"&js_code="+code+"&grant_type=authorization_code";
System.out.println(requestUrl);
String Result = httpsRequest(requestUrl, "GET", null);
JSONObject jsonObject = JSONObject.fromObject(Result);
System.out.println(jsonObject);
return jsonObject.toString();
}
@ResponseBody
@RequestMapping("/sendMessage")
public String sendMessage(@RequestParam String openid){
sendMessageUtils(openid);
return "ok";
}
}
三个实体类,Token、Template、TemplateParam:主要是用来封装模板消息的格式。不用做过多研究,
其中的Token是比较重要的一个东西,类似与一种凭证。每次获取有7200秒的有效时间
package com.buyixs.demo.entity;
import java.util.List;
public class Template
{
private String touser;
private String template_id;
private String page;
private List<TemplateParam> templateParamList;
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 String toJSON() {
StringBuffer buffer = new StringBuffer();
buffer.append("{");
buffer.append(String.format("\"touser\":\"%s\"", this.touser)).append(",");
buffer.append(String.format("\"template_id\":\"%s\"", this.template_id)).append(",");
buffer.append(String.format("\"page\":\"%s\"", this.page)).append(",");
buffer.append("\"data\":{");
TemplateParam param = null;
for (int i = 0; i < this.templateParamList.size(); i++) {
param = templateParamList.get(i);
// 判断是否追加逗号
if (i < this.templateParamList.size() - 1){
buffer.append(String.format("\"%s\": {\"value\":\"%s\"},", param.getKey(), param.getValue()));
}else{
buffer.append(String.format("\"%s\": {\"value\":\"%s\"}", param.getKey(), param.getValue()));
}
}
buffer.append("}");
buffer.append("}");
return buffer.toString();
}
public List<TemplateParam> getTemplateParamList() {
return templateParamList;
}
public void setTemplateParamList(List<TemplateParam> templateParamList) {
this.templateParamList = templateParamList;
}
}
package com.buyixs.demo.entity;
public class TemplateParam
{
private String key;
private String value;
public TemplateParam(String key,String value){
this.key=key;
this.value=value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
package com.buyixs.demo.entity;
public class Token
{
private String accessToken;
private int expiresIn;
private long getTokenTime;
public long getGetTokenTime()
{
return this.getTokenTime;
}
public void setGetTokenTime(long getTokenTime)
{
this.getTokenTime = getTokenTime;
}
public String getAccessToken()
{
return this.accessToken;
}
public void setAccessToken(String accessToken)
{
this.accessToken = accessToken;
}
public int getExpiresIn()
{
return this.expiresIn;
}
public void setExpiresIn(int expiresIn)
{
this.expiresIn = expiresIn;
}
}
接下来是最后一个工具类
package com.buyixs.demo.utils;
import com.buyixs.demo.entity.Template;
import com.buyixs.demo.entity.TemplateParam;
import com.buyixs.demo.entity.Token;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class WxgzhUtil {
@Autowired
private static final Logger log = LoggerFactory.getLogger(WxgzhUtil.class);
private static Token token = null;
/**
* http请求方法
* @param requestUrl
* @param requestMethod
* @param outputStr
* @return
*/
public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
try {
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod(requestMethod);
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
if (outputStr != null) {
OutputStream outputStream = conn.getOutputStream();
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
conn.disconnect();
return buffer.toString();
} catch (ConnectException ce) {
System.out.println("连接超时:{}");
} catch (Exception e) {
System.out.println("https请求异常:{}");
}
return null;
}
/**
* 发送模板消息
*
* @param template
* @return
*/
public static boolean sendTemplateMsg(Template template) {
boolean flag = false;
String requestUrl = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN";
requestUrl = requestUrl.replace("ACCESS_TOKEN", getToken().getAccessToken());
String Result = httpsRequest(requestUrl, "POST", template.toJSON());
System.out.println(Result);
new JSONObject();
JSONObject jsonResult = JSONObject.fromObject(Result);
if (jsonResult != null) {
int errorCode = jsonResult.getInt("errcode");
String errorMessage = jsonResult.getString("errmsg");
if (errorCode == 0) {
flag = true;
} else {
System.out.println("模板消息发送失败:" + errorCode + "," + errorMessage);
}
}
return flag;
}
// 测试
public static void main(String[] args) {
Template template=new Template();
//这里填写模板ID
template.setTemplate_id("F_tOEAVSd5HP904M7u2WiAt2g0jsMcX8ARWEVRl9NfE");
//这里填写用户的openid
template.setTouser("oBVWv4qBXi7Tnp-c7RwdJyYgRK0w");
//这里填写点击订阅消息后跳转小程序的界面
template.setPage("pages/progress/progressList");
List<TemplateParam> paras=new ArrayList<>();
paras.add(new TemplateParam("car_number1","川AED606"));
paras.add(new TemplateParam("thing2","维修完成"));
paras.add(new TemplateParam("date3","2019-12-18 09:23:09"));
paras.add(new TemplateParam("thing4","测试订阅号"));
template.setTemplateParamList(paras);
sendTemplateMsg(template);
}
// 测试
public static void sendMessageUtils(String openid) {
Template template=new Template();
//这里填写模板ID
template.setTemplate_id("F_tOEAVSd5HP904M7u2WiAt2g0jsMcX8ARWEVRl9NfE");
//这里填写用户的openid
template.setTouser(openid);
//这里填写点击订阅消息后跳转小程序的界面
template.setPage("pages/index/index");
List<TemplateParam> paras=new ArrayList<>();
paras.add(new TemplateParam("car_number1","川AED606"));
paras.add(new TemplateParam("thing2","维修完成"));
paras.add(new TemplateParam("date3","2019-12-18 09:23:09"));
paras.add(new TemplateParam("thing4","测试订阅号"));
template.setTemplateParamList(paras);
sendTemplateMsg(template);
}
/**
* 获取有效的token
* @return
*/
public static Token getToken() {
if (token != null) {
if (token.getGetTokenTime() + token.getExpiresIn() > new Date()
.getTime()) {
return token;
}
}
//记得补充上appid和appsecret
String appid="";
String secret="";
String result = httpsRequest(
//appid 小程序的id,appsecret,请替换当前的
"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret,
"GET", null);
new JSONObject();
JSONObject jsonObject = JSONObject.fromObject(result);
if (jsonObject != null) {
try {
token = new Token();
token.setGetTokenTime(new Date().getTime());
token.setAccessToken(jsonObject.getString("access_token"));
token.setExpiresIn(jsonObject.getInt("expires_in"));
System.out.println("成功");
} catch (JSONException e) {
System.out.println("失败");
token = null;
log.error("获取token失败 errcode:{} errmsg:{}",
Integer.valueOf(jsonObject.getInt("errcode")),
jsonObject.getString("errmsg"));
}
}
return token;
}
}
OK JAVA 代码 至此写完了,接下来 我们来看小程序的代码。
先给大家看一下小程序的目录
这是index.wxml
<view class="main_box">
<view class="service_notice"><button bindtap="btn" >开启订阅消息</button></view>
</view>
<button bindtap="send">发送订阅消息</button>
这是index.wxss
/* keyboard.wxss */
.service_notice{
margin: auto;
width: 90%;
display: flex;
justify-content: space-between;
border-bottom: 4rpx solid rgb(235,235,235);
height: 80rpx;
line-height: 80rpx;
}
.main_box{
background-color: white;
}
这是index.js
Page({
data: {
switch1Checked:false,
openid:''
},
onLoad: function (options) {
var that=this
//获取用户的微信凭证 openid
// -----------------------------------------------
wx.login({
success: function (res) {
//获取登录的临时凭证
var code = res.code;
wx.request({
url: 'http://localhost:8080/wxController/getUserInfo',
data: {
code: code,
},
header: {
'content-type': 'application/json'
},
success(res) {
console.log("openid获取")
console.log(res.data.openid)
that.setData({
openid: res.data.openid
})
}
})
}
})
},
btn: function (enent){
wx.requestSubscribeMessage({
tmplIds: ['F_tOEAVSd5HP904M7u2WiAt2g0jsMcX8ARWEVRl9NfE'],
success(res) {
console.log(res)
if (res['F_tOEAVSd5HP904M7u2WiAt2g0jsMcX8ARWEVRl9NfE'] == "reject") {
console.log("用户拒绝了订阅消息")
}else {
console.log("用户接受了订阅消息")
}
},
})
},
//
send:function(){
wx.request({
url: 'http://localhost:8080/wxController/sendMessage',
data: {
openid: this.data.openid,
},
header: {
'content-type': 'application/json'
},
success(res) {
console.log(res)
}
})
},
})
OK至此所有代码已经敲完,接下来 我们来看看 具体的实例演示
我们先运行springBoot项目
然后打开小程序开发者工具进行测试
这里订阅消息绑定的事件必须是 bindtap 类型,才能触发wx.requestSubscribeMessage()
最后我们点击发送订阅消息
然后看看 java后台是有发送成功的提示
最后 我们再打开手机看看 是否有订阅消息发送到手机上,当然,必须是和开发者工具绑定的手机才能有消息。
发送成功。
ok,教程到此结束了,如果还有没弄出来的,可以私信我,免费为你们解答。