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

订阅消息说明

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

订阅消息的功能较模板消息有所提升,"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后端实现)开发的文章就介绍到这了,更多相关小程序订阅消息内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 微信小程序+后端(java)实现开发

    前言 现在微信小程序越来越火了,相信不少人都通过各种途径学习过微信小程序或者尝试开发,作者就是曾经由于兴趣了解开发过微信小程序,最终自己的毕业设计也是开发一个微信小程序.所以现在用这篇博客记录我之前开发的一些经验和一些心得吧. 主要内容 springboot后端架构构建 小程序项目构建 小程序api调用 后台resetful接口编写 小程序调用后台接口 免费的https申请 linux下部署上线 微信小程序项目构建 这些基础的东西我就不过多介绍,大家在刚开始开发的时候一般都没有自己的服务器及域名

  • Java解密微信小程序手机号的方法

    本文实例为大家分享了Java解密微信小程序手机号的具体代码,供大家参考,具体内容如下 第一步:创建AES解密工具类:代码如下 import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySp

  • 微信小程序调用微信登陆获取openid及java做为服务端示例

    一.微信小程序 第一步:调用 wx.login获取code 文档地址 第二步:判断用户是否授权读取用户信息 文档地址 第三步:调用wx.getUserInfo读取用户数据 文档地址 第四步:由于小程序后台授权域名无法授权微信的域名,所以我们只能通过我们自己的服务器去调用微信服务器去获取用户信息,故我们将wx.login获取code 和 wx.getUserInfo 获取的encryptedData与iv 通过wx.request 请求传入后台 服务器返回的数据: 小程序代码: //调用登录接口,

  • java实现微信小程序登录态维护的示例代码

    相信不少喜欢开发的朋友都已经知道微信小程序是个什么物种了,楼主也是从小程序内测期间就开始关注,并且也写过几个已经上线的微信小程序.但是基本上都是写的纯前端,最近楼主从后端到前端写一个完整的小程序项目,中间碰到了一些问题,楼主会找一些个人觉得有学习价值的点不定时的拿出来跟大家分享,希望对你有一些帮助. 本次就从最基本的微信小程序登录态维护开始吧.小程序官方api文档里面有对登录态的一个完整的解释,并且有相关的代码.想看详情,可以出门右转:https://mp.weixin.qq.com/debug

  • 微信小程序实现获取小程序码和二维码java接口开发

    前言:目前小程序推出了自己的识别码,小程序码,这个圆形的码看起来比二维码好看.本文总结微信小程序的获取小程序码和二维码并生成二维码图片的接口开发.主要内容摘抄自微信小程序的API文档,java接口开发是自己总结开发. 微信小程序API文档:获取二维码 一.简介 通过后台接口可以获取小程序任意页面的二维码,扫描该二维码可以直接进入小程序对应的页面.目前微信支持两种二维码,小程序码(左),小程序二维码(右),如下所示: 二.获取小程序码 目前有两个接口可以生成小程序码,开发者可以根据自己的需要选择合

  • 微信小程序 支付后台java实现实例

    微信小程序 支付后台java实现实例 前言: 前些天使用 LeanCloud 云引擎写了个小程序的支付相关 以前只做过 APP 支付 这次在小程序支付爬了两天的坑 把代码也分享出来 支付流程: 1.小程序前端获取微信 openId 以及订单号 传给后台 2,后台根据 openId 和订单号进行签名 post 微信统一下单接口 3.后台获取微信返回的xml字符串 解析 二次签名以后返回给前端 4.前端调起支付微信支付 API 先看支付函数: //获取支付信息 @EngineFunction("ge

  • 微信小程序获取手机号,后端JAVA解密流程代码

    小程序获取手机号,后端JAVA解密流程代码 微信官方文档获取手机号流程地址,先看下最好方便理解下面步骤 实现思路,步骤如下 1.前端需先调用官方wx.login接口获取登录凭证code. 2.后端接收code 调用官方接口地址获取用户秘钥 sessionKey. 3.前端通过官方getPhoneNumber获取encryptedData,iv 4.前端通过参数**[encryptedData] .[iv] .[sessionKey]** 发送请求后端接口,解密用户手机号 小程序获取session

  • Java中基于Shiro,JWT实现微信小程序登录完整例子及实现过程

    小程序官方流程图如下,官方地址 : https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html : 本文是对接微信小程序自定义登录的一个完整例子实现 ,技术栈为 : SpringBoot+Shiro+JWT+JPA+Redis. 如果对该例子比较感兴趣或者觉得言语表达比较啰嗦,可查看完整的项目地址 : https://github.com/EalenXie/shiro-jwt-applet

  • 微信小程序后端(java)开发流程的详细步骤

    微信小程序后端开发流程根据官网总结为两个步骤 1.前端调用 wx.login 返回了code,然后调用wx.getUserInfo获取到用户的昵称 头像 2.服务端根据code去微信获取openid, 接口地址: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html%EF%BC%9B%E5%90%8C%E6%97%B6%EF%BC%8C%E6%9B%B4

  • java实现微信小程序加密数据解密算法

    一.概述 微信推出了小程序,很多公司的客户端应用不仅具有了APP.H5.还接入了小程序开发.但是,小程序中竟然没有提供Java版本的加密数据解密算法.这着实让广大的Java开发人员蛋疼. 微信小程序提供的加密数据解密算法链接 我们下载的算法示例如下: 木有Java!! 木有Java!! 木有Java!! 那么如何解决这个问题,我们一起来实现Java版本的微信小程序加密数据解密算法. 二.实现Java版本的微信小程序加密数据解密算法 1.创建项目 这里,我们创建一个Maven工程,具体创建步骤略.

  • Java微信小程序oss图片上传的实现方法

    先将图片上传到服务器,再将服务器上的图片传入oss中 小程序js //启动上传等待中... wx.showToast({ title: '正在上传...', icon: 'loading', mask: true, duration: 10000 }) //上传图片 wx.uploadFile({ url: '***********',//上传的路径(Java后台路径) filePath: tempFilePaths[0], name: 'file', success: function (re

  • java与微信小程序实现websocket长连接

    本文实例为大家分享了java与微信小程序实现websocket长连接的具体代码,供大家参考,具体内容如下 背景: 需要在小程序实现地图固定坐标下实时查看消息 java环境 :tomcat7 jdk1.7 1.java websocket 类 package com.qs.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.

  • 微信小程序登录状态java后台解密

    一.登录流程图 二.微信小程序端 doLogin:function(callback = () =>{}){ let that = this; wx.login({ success:function(loginRes){ if(loginRes){ //获取用户信息 wx.getUserInfo({ withCredentials:true,//非必填 默认为true success:function(infoRes){ console.log(infoRes,'>>>'); //

  • java遇到微信小程序 "支付验证签名失败" 问题解决

    最近在做一个微信小程序项目做到微信支付的时候遇到的一些问题! 详细步骤: 开发前准备(必须) 小程序标识(appid):wx4d4838ebec29b8** 商户号(mch_id):15508070** 商户密钥(key) :wHtQckdfiRBVF7ceGTcSWEEORt6C0D** 我们用微信官方提供的SDK开发 :https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1 下载 SDK完成后 : 开始写我们的程 进入微信

  • 微信小程序如何连接Java后台

    前端时间有人问我小程序怎么连接后台,这里直接贴代码 在app.js里 // api request request(url, params) { return new Promise((resolve, reject) => { wx.request({ url: baseUrl + url, method: 'POST', data: params, success(res) { console.log(res.data) resolve(res.data) }, fail(res) { co

随机推荐