微信小程序订阅消息(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 获取radio按钮值的实例
Aug 17 Javascript
关于Javascript作用域链的八点总结
Dec 06 Javascript
ECMAScript5(ES5)中bind方法使用小结
May 07 Javascript
JavaScript sort数组排序方法和自我实现排序方法小结
Jun 06 Javascript
使用RequireJS库加载JavaScript模块的实例教程
Jun 06 Javascript
JS点击图片弹出文件选择框并覆盖原图功能的实现代码
Aug 25 Javascript
Vue.js 2.5新特性介绍(推荐)
Oct 24 Javascript
JavaScript设计模式之装饰者模式定义与应用示例
Jul 25 Javascript
Node.js事件的正确使用方法
Apr 05 Javascript
JavaScript鼠标拖拽事件详解
Apr 03 Javascript
原生JS实现分页
Apr 19 Javascript
JS前端可视化canvas动画原理及其推导实现
Aug 05 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
Classes and Objects in PHP5-面向对象编程 [1]
2006/10/09 PHP
简单易用的计数器(数据库)
2006/10/09 PHP
php生成文件
2007/01/15 PHP
PHP脚本监控Nginx 502错误并自动重启php-fpm
2015/05/13 PHP
在Mac OS上搭建PHP的Yii框架及相关测试环境
2016/02/14 PHP
PHP函数import_request_variables()用法分析
2016/04/02 PHP
PHP实现动态压缩js与css文件的方法
2018/05/02 PHP
php实现图片压缩处理
2020/09/09 PHP
Aster vs KG BO3 第二场2.19
2021/03/10 DOTA
jquery获取div宽度的实现思路与代码
2013/01/13 Javascript
Jquery 类网页微信二维码图块滚动效果具体实现
2013/10/14 Javascript
jquery使用each方法遍历json格式数据实例
2015/05/18 Javascript
jQuery侧边栏实现代码
2016/05/06 Javascript
AngularJs Dependency Injection(DI,依赖注入)
2016/09/02 Javascript
详解前端自动化工具gulp自动添加版本号
2016/12/20 Javascript
微信小程序 转发功能的实现
2017/08/04 Javascript
JavaScript实现带有子菜单和控件的slider轮播图效果
2017/11/01 Javascript
详解微信小程序之scroll-view的flex布局问题
2019/01/16 Javascript
element-ui多文件上传的实现示例
2019/04/10 Javascript
微信小程序登录对接Django后端实现JWT方式验证登录详解
2019/07/29 Javascript
Python中GeoJson和bokeh-1的使用讲解
2019/01/03 Python
Python中字符串String的基本内置函数与过滤字符模块函数的基本用法
2019/05/27 Python
Python Pandas 箱线图的实现
2019/07/23 Python
基于python使用tibco ems代码实例
2019/12/20 Python
python几种常用功能实现代码实例
2019/12/25 Python
AmazeUI图片轮播效果的示例代码
2020/08/20 HTML / CSS
英国虚拟主机服务商:eUKhost
2016/08/16 全球购物
Expedia爱尔兰:酒店、机票、租车及廉价假期
2017/01/02 全球购物
几个Shell Script面试题
2014/04/18 面试题
化学教师教学反思
2014/01/17 职场文书
企业标语口号
2014/06/10 职场文书
党的群众路线教育实践活动对照检查材料(教师)
2014/09/24 职场文书
正风肃纪剖析材料
2014/09/30 职场文书
超市员工辞职信范文
2015/05/12 职场文书
创业计划书之外语培训班
2019/11/02 职场文书
如何用vue实现网页截图你知道吗
2021/11/17 Vue.js