微信小程序订阅消息(java后端实现)开发


Posted in Javascript onJune 01, 2020

订阅消息说明

订阅消息是微信近期新出的一个能力,用来代替原有的模板消息(原有的模板消息即将下线)

订阅消息的功能较模板消息有所提升,"7天"的限制取消,同时有"一次性"和"永久"订阅.(功能上是这样说的,但是实际开发时发现"永久"订阅还是对小程序的服务类目有要求的,客户的小程序只支持"一次性"订阅)

官方通道:
小程序前端:点击进入
小程序服务端:点击进入

开发思路

用户在小程序内触发按钮或进行支付操作时前端调用订阅消息授权框,默认一次授权只能发送一次订阅消息
如果用户勾选"下次自动授权",下次将不再弹出授权框->点击按钮直接拥有一次发送订阅消息的机会,此处不需要模板消息的"formId",较之前更简单
经过测试,如果在小程序上多次点击触发授权的按钮,发送订阅消息的机会可以累加!!!
(如,1分钟内点击了10次按钮,后面将拥有10次发送订阅消息的机会,什么时候发都可以)

代码实现(仅java后端)

实体类部分

1.TemplateParam.java

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;
} 
 
}

2.Template.java

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; 
} 
}

工具类部分

1.CommonUtil.java

import java.io.BufferedReader; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.io.UnsupportedEncodingException; 
import java.net.ConnectException; 
import java.net.HttpURLConnection; 
import java.net.URL; 

import javax.net.ssl.HttpsURLConnection; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLSocketFactory; 
import javax.net.ssl.TrustManager; 

import net.sf.json.JSONObject; 

public class CommonUtil { 
 
public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) { 
  
 JSONObject jsonObject = null; 
 StringBuffer buffer = new StringBuffer(); 
 try { 
  // 创建SSLContext对象,并使用我们指定的信任管理器初始化 
  TrustManager[] tm = { new MyX509TrustManager() }; 
  SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); 
  sslContext.init(null, tm, new java.security.SecureRandom()); 
  // 从上述SSLContext对象中得到SSLSocketFactory对象 
  SSLSocketFactory ssf = sslContext.getSocketFactory(); 

  URL url = new URL(requestUrl); 
  HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); 
  httpUrlConn.setSSLSocketFactory(ssf); 

  httpUrlConn.setDoOutput(true); 
  httpUrlConn.setDoInput(true); 
  httpUrlConn.setUseCaches(false); 
  // 设置请求方式(GET/POST) 
  httpUrlConn.setRequestMethod(requestMethod); 

  if ("GET".equalsIgnoreCase(requestMethod)) { 
    httpUrlConn.connect(); 
  } 
    

  // 当有数据需要提交时 
  if (null != outputStr) { 
   OutputStream outputStream = httpUrlConn.getOutputStream(); 
   // 注意编码格式,防止中文乱码 
   outputStream.write(outputStr.getBytes("UTF-8")); 
   outputStream.close(); 
  } 

  // 将返回的输入流转换成字符串 
  InputStream inputStream = httpUrlConn.getInputStream(); 
  InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); 
  BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 

  String str = null; 
  while ((str = bufferedReader.readLine()) != null) { 
   buffer.append(str); 
  } 
  bufferedReader.close(); 
  inputStreamReader.close(); 
  // 释放资源 
  inputStream.close(); 
  inputStream = null; 
  httpUrlConn.disconnect(); 
  jsonObject = JSONObject.fromObject(buffer.toString()); 
 } catch (ConnectException ce) { 
  ce.printStackTrace(); 
 } catch (Exception e) { 
  e.printStackTrace(); 
 } 
 return jsonObject; 
} 
 
public static String httpRequest(String requestUrl, String requestMethod, String outputStr) { 
  
  
 StringBuffer buffer = new StringBuffer(); 
 try { 
  

  URL url = new URL(requestUrl); 
  HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection(); 
   

  httpUrlConn.setDoOutput(true); 
  httpUrlConn.setDoInput(true); 
  httpUrlConn.setUseCaches(false); 
  // 设置请求方式(GET/POST) 
  httpUrlConn.setRequestMethod(requestMethod); 

  if ("GET".equalsIgnoreCase(requestMethod)) { 
    httpUrlConn.connect(); 
  } 
    

  // 当有数据需要提交时 
  if (null != outputStr) { 
   OutputStream outputStream = httpUrlConn.getOutputStream(); 
   // 注意编码格式,防止中文乱码 
   outputStream.write(outputStr.getBytes("UTF-8")); 
   outputStream.close(); 
  } 

  // 将返回的输入流转换成字符串 
  InputStream inputStream = httpUrlConn.getInputStream(); 
  InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); 
  BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 

  String str = null; 
  while ((str = bufferedReader.readLine()) != null) { 
   buffer.append(str); 
  } 
  bufferedReader.close(); 
  inputStreamReader.close(); 
  // 释放资源 
  inputStream.close(); 
  inputStream = null; 
  httpUrlConn.disconnect(); 
  //jsonObject = JSONObject.fromObject(buffer.toString()); 
 } catch (ConnectException ce) { 
  ce.printStackTrace(); 
 } catch (Exception e) { 
  e.printStackTrace(); 
 } 
 return buffer.toString(); 
} 
public static String urlEncodeUTF8(String source){ 
 String result = source; 
 try { 
  result = java.net.URLEncoder.encode(source,"utf-8"); 
 } catch (UnsupportedEncodingException e) { 
  e.printStackTrace(); 
 } 
 return result; 
} 
 
public static String httpsRequestForStr(String requestUrl, String requestMethod, String outputStr) { 
  
 String result=""; 
 StringBuffer buffer = new StringBuffer(); 
 try { 
  // 创建SSLContext对象,并使用我们指定的信任管理器初始化 
  TrustManager[] tm = { new MyX509TrustManager() }; 
  SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); 
  sslContext.init(null, tm, new java.security.SecureRandom()); 
  // 从上述SSLContext对象中得到SSLSocketFactory对象 
  SSLSocketFactory ssf = sslContext.getSocketFactory(); 

  URL url = new URL(requestUrl); 
  HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); 
  httpUrlConn.setSSLSocketFactory(ssf); 

  httpUrlConn.setDoOutput(true); 
  httpUrlConn.setDoInput(true); 
  httpUrlConn.setUseCaches(false); 
  // 设置请求方式(GET/POST) 
  httpUrlConn.setRequestMethod(requestMethod); 

  if ("GET".equalsIgnoreCase(requestMethod)) { 
    httpUrlConn.connect(); 
  } 
    

  // 当有数据需要提交时 
  if (null != outputStr) { 
   OutputStream outputStream = httpUrlConn.getOutputStream(); 
   // 注意编码格式,防止中文乱码 
   outputStream.write(outputStr.getBytes("UTF-8")); 
   outputStream.close(); 
  } 

  // 将返回的输入流转换成字符串 
  InputStream inputStream = httpUrlConn.getInputStream(); 
  InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); 
  BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 

  String str = null; 
  while ((str = bufferedReader.readLine()) != null) { 
   buffer.append(str); 
  } 
  bufferedReader.close(); 
  inputStreamReader.close(); 
  // 释放资源 
  inputStream.close(); 
  inputStream = null; 
  httpUrlConn.disconnect(); 
  result=buffer.toString(); 
 } catch (ConnectException ce) { 
  ce.printStackTrace(); 
 } catch (Exception e) { 
  e.printStackTrace(); 
 } 
 return result; 
} 
 
}

2.HttpUtil.java

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpUtil {

private static final CloseableHttpClient httpclient = HttpClients.createDefault();

/**
 * 发送HttpGet请求
 * @param url
 * @return
 */
public static String sendGet(String url) {

 HttpGet httpget = new HttpGet(url);
 CloseableHttpResponse response = null;
 try {
  response = httpclient.execute(httpget);
 } catch (IOException e1) {
  e1.printStackTrace();
 }
 String result = null;
 try {
  HttpEntity entity = response.getEntity();
  if (entity != null) {
   result = EntityUtils.toString(entity);
  }
 } catch (Exception e) {
  e.printStackTrace();
 } finally {
  try {
   response.close();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 return result;
}

/**
 * 发送HttpPost请求,参数为map
 * @param url
 * @param map
 * @return
 */
public static String sendPost(String url, Map<String, String> map) {
 List<NameValuePair> formparams = new ArrayList<NameValuePair>();
 for (Map.Entry<String, String> entry : map.entrySet()) {
  formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
 }
 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
 HttpPost httppost = new HttpPost(url);
 httppost.setEntity(entity);
 CloseableHttpResponse response = null;
 try {
  response = httpclient.execute(httppost);
 } catch (IOException e) {
  e.printStackTrace();
 }
 HttpEntity entity1 = response.getEntity();
 String result = null;
 try {
  result = EntityUtils.toString(entity1);
 } catch (Exception e) {
  e.printStackTrace();
 }
 return result;
}

/**
 * 发送不带参数的HttpPost请求
 * @param url
 * @return
 */
public static String sendPost(String url) {
 HttpPost httppost = new HttpPost(url);
 CloseableHttpResponse response = null;
 try {
  response = httpclient.execute(httppost);
 } catch (IOException e) {
  e.printStackTrace();
 }
 HttpEntity entity = response.getEntity();
 String result = null;
 try {
  result = EntityUtils.toString(entity);
 } catch (Exception e) {
  e.printStackTrace();
 }
 return result;
}
 
}

jar包:

1.fastjson-1.2.44.jar

控制层代码:

1.获取ACCESS_TOKEN

String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
 + 小程序的appid
 + "&secret="
 + 小程序的Secret
 String result = HttpUtil.sendGet(url);
 JSONObject object=JSON.parseObject(result);
 String Access_Token = object.getString("access_token");

2.发送订阅消息

Template template=new Template(); 
 template.setTemplate_id("填写小程序申请的订阅消息id"); 
 template.setTouser("用户的openid");
 template.setPage("pages/index/index");
 List<TemplateParam> paras=new ArrayList<TemplateParam>(); 
 paras.add(new TemplateParam("character_string2","000001")); 
 paras.add(new TemplateParam("amount1","888.88")); 
 paras.add(new TemplateParam("date3","2015年01月05日")); 
 paras.add(new TemplateParam("thing4","请进入小程序查1看")); 
 template.setTemplateParamList(paras); 
  String requestUrl="https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN"; 
  requestUrl=requestUrl.replace("ACCESS_TOKEN", Access_Token);  
  
  System.out.println(template.toJSON());
  net.sf.json.JSONObject jsonResult=CommonUtil.httpsRequest(requestUrl, "POST", template.toJSON()); 
  if(jsonResult!=null){ 
  System.out.println(jsonResult);
   int errorCode=jsonResult.getInt("errcode"); 
   String errorMessage=jsonResult.getString("errmsg"); 
   if(errorCode==0){ 
    System.out.println("Send Success");
   }else{ 
    System.out.println("订阅消息发送失败:"+errorCode+","+errorMessage); 
   } 
  }

总结

1.本文阅读对象为初学者,所有各种工具类.jar包都粘出来了,直接复制即可使用
2.通过该功能的开发,发现小程序的通知类功能监管更加严格,必须用户授权才可以发订阅消息,同时用户可以更方便的取消订阅,所以建议开发者慎用此功能

到此这篇关于微信小程序订阅消息(java后端实现)开发的文章就介绍到这了,更多相关小程序订阅消息内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
JS 控件事件小结
Oct 31 Javascript
JQuery EasyUI 日期控件如何控制日期选择区间
May 05 Javascript
Angular.js回顾ng-app和ng-model使用技巧
Apr 26 Javascript
使用jquery.form.js实现图片上传的方法
May 05 Javascript
微信小程序 wxapp视图容器 view详解
Oct 31 Javascript
bootstarp modal框居中显示的实现代码
Feb 18 Javascript
Vue.js展示AJAX数据简单示例讲解
Mar 29 Javascript
基于 Vue 实现一个酷炫的 menu插件
Nov 14 Javascript
javascript for循环性能测试示例
Aug 07 Javascript
在vue和element-ui的table中实现分页复选功能
Dec 04 Javascript
JS猜数字游戏实例讲解
Jun 30 Javascript
js实现鼠标拖曳效果
Dec 30 Javascript
微信小程序开发(三):返回上一级页面并刷新操作示例【页面栈】
Jun 01 #Javascript
微信小程序开发(二):页面跳转并传参操作示例
Jun 01 #Javascript
5个你不知道的JavaScript字符串处理库(小结)
Jun 01 #Javascript
基于Vue sessionStorage实现保留搜索框搜索内容
Jun 01 #Javascript
微信小程序开发(一):服务器获取数据列表渲染操作示例
Jun 01 #Javascript
JavaScript forEach中return失效问题解决方案
Jun 01 #Javascript
原生JS封装拖动验证滑块的实现代码示例
Jun 01 #Javascript
You might like
DOTA2【瓜皮时刻】Vol.91 RTZ山史最惨“矿难”
2021/03/05 DOTA
PHP合并数组+与array_merge的区别分析
2010/08/01 PHP
discuz加密解密函数使用方法和中文注释
2014/01/21 PHP
Codeigniter框架的更新事务(transaction)BUG及解决方法
2014/07/25 PHP
两种php去除二维数组的重复项方法
2015/11/04 PHP
PHP用户验证和标签推荐的简单使用
2016/10/31 PHP
PHP7 整型处理机制修改
2021/03/09 PHP
javascript下过滤数组重复值的代码
2007/09/10 Javascript
Jquery AJAX 框架的使用方法
2009/11/03 Javascript
AngularJS中取消对HTML片段转义的方法例子
2015/01/04 Javascript
理解javascript定时器中的setTimeout与setInterval
2016/02/23 Javascript
基于jQuery倒计时插件实现团购秒杀效果
2016/05/13 Javascript
微信小程序 使用picker封装省市区三级联动实例代码
2016/10/28 Javascript
js中Number数字数值运算后值不对的解决方法
2017/02/28 Javascript
微信小程序 支付功能(前端)的实现
2017/05/24 Javascript
基于Particles.js制作超炫粒子动态背景效果(仿知乎)
2017/09/13 Javascript
jQuery实现的两种简单弹窗效果示例
2018/04/18 jQuery
Layui给数据表格动态添加一行并跳转到添加行所在页的方法
2018/08/20 Javascript
Vue路由对象属性 .meta $route.matched详解
2019/11/04 Javascript
如何利用node.js开发一个生成逐帧动画的小工具
2019/12/01 Javascript
用云开发Cloudbase实现小程序多图片内容安全监测的代码详解
2020/06/07 Javascript
可拖拽组件slider.js使用方法详解
2020/12/04 Javascript
vue编写简单的购物车功能
2021/01/08 Vue.js
python抓取网页时字符集转换问题处理方案分享
2014/06/19 Python
使用python编写简单的小程序编译成exe跑在win10上
2018/01/15 Python
python3调用百度翻译API实现实时翻译
2018/08/16 Python
python 多线程中子线程和主线程相互通信方法
2018/11/09 Python
python web框架Flask实现图形验证码及验证码的动态刷新实例
2019/10/14 Python
Python文本文件的合并操作方法代码实例
2020/03/31 Python
印尼网上商店:Alfacart.com
2019/03/11 全球购物
来自南加州灵感的工作和娱乐服装:TravisMathew
2019/05/01 全球购物
内勤主管岗位职责
2014/04/03 职场文书
党员承诺践诺书
2014/05/20 职场文书
放牛班的春天观后感
2015/06/01 职场文书
工作简报怎么写
2015/07/21 职场文书
五星级酒店宣传口号
2015/12/25 职场文书