微信小程序訂閱消息(java后端實(shí)現(xiàn))開發(fā)
訂閱消息說(shuō)明
訂閱消息是微信近期新出的一個(gè)能力,用來(lái)代替原有的模板消息(原有的模板消息即將下線)
訂閱消息的功能較模板消息有所提升,"7天"的限制取消,同時(shí)有"一次性"和"永久"訂閱.(功能上是這樣說(shuō)的,但是實(shí)際開發(fā)時(shí)發(fā)現(xiàn)"永久"訂閱還是對(duì)小程序的服務(wù)類目有要求的,客戶的小程序只支持"一次性"訂閱)
官方通道:
小程序前端:點(diǎn)擊進(jìn)入
小程序服務(wù)端:點(diǎn)擊進(jìn)入
開發(fā)思路
用戶在小程序內(nèi)觸發(fā)按鈕或進(jìn)行支付操作時(shí)前端調(diào)用訂閱消息授權(quán)框,默認(rèn)一次授權(quán)只能發(fā)送一次訂閱消息
如果用戶勾選"下次自動(dòng)授權(quán)",下次將不再?gòu)棾鍪跈?quán)框->點(diǎn)擊按鈕直接擁有一次發(fā)送訂閱消息的機(jī)會(huì),此處不需要模板消息的"formId",較之前更簡(jiǎn)單
經(jīng)過(guò)測(cè)試,如果在小程序上多次點(diǎn)擊觸發(fā)授權(quán)的按鈕,發(fā)送訂閱消息的機(jī)會(huì)可以累加!!!
(如,1分鐘內(nèi)點(diǎn)擊了10次按鈕,后面將擁有10次發(fā)送訂閱消息的機(jī)會(huì),什么時(shí)候發(fā)都可以)
代碼實(shí)現(xiàn)(僅java后端)
實(shí)體類部分
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);
// 判斷是否追加逗號(hào)
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 {
// 創(chuàng)建SSLContext對(duì)象,并使用我們指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 從上述SSLContext對(duì)象中得到SSLSocketFactory對(duì)象
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);
// 設(shè)置請(qǐng)求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod)) {
httpUrlConn.connect();
}
// 當(dāng)有數(shù)據(jù)需要提交時(shí)
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意編碼格式,防止中文亂碼
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 將返回的輸入流轉(zhuǎn)換成字符串
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);
// 設(shè)置請(qǐng)求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod)) {
httpUrlConn.connect();
}
// 當(dāng)有數(shù)據(jù)需要提交時(shí)
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意編碼格式,防止中文亂碼
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 將返回的輸入流轉(zhuǎn)換成字符串
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 {
// 創(chuàng)建SSLContext對(duì)象,并使用我們指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 從上述SSLContext對(duì)象中得到SSLSocketFactory對(duì)象
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);
// 設(shè)置請(qǐng)求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod)) {
httpUrlConn.connect();
}
// 當(dāng)有數(shù)據(jù)需要提交時(shí)
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意編碼格式,防止中文亂碼
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 將返回的輸入流轉(zhuǎn)換成字符串
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();
/**
* 發(fā)送HttpGet請(qǐng)求
* @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;
}
/**
* 發(fā)送HttpPost請(qǐng)求,參數(shù)為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;
}
/**
* 發(fā)送不帶參數(shù)的HttpPost請(qǐng)求
* @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.發(fā)送訂閱消息
Template template=new Template();
template.setTemplate_id("填寫小程序申請(qǐng)的訂閱消息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","請(qǐng)進(jìn)入小程序查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("訂閱消息發(fā)送失敗:"+errorCode+","+errorMessage);
}
}
總結(jié)
1.本文閱讀對(duì)象為初學(xué)者,所有各種工具類.jar包都粘出來(lái)了,直接復(fù)制即可使用
2.通過(guò)該功能的開發(fā),發(fā)現(xiàn)小程序的通知類功能監(jiān)管更加嚴(yán)格,必須用戶授權(quán)才可以發(fā)訂閱消息,同時(shí)用戶可以更方便的取消訂閱,所以建議開發(fā)者慎用此功能
到此這篇關(guān)于微信小程序訂閱消息(java后端實(shí)現(xiàn))開發(fā)的文章就介紹到這了,更多相關(guān)小程序訂閱消息內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript棧和隊(duì)列相關(guān)操作與實(shí)現(xiàn)方法詳解
這篇文章主要介紹了JavaScript棧和隊(duì)列相關(guān)操作與實(shí)現(xiàn)方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了javascript棧和隊(duì)列的概念、原理、定義、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2018-12-12
35個(gè)JS中實(shí)用工具函數(shù)的代碼分享
身為后臺(tái)開發(fā)的各位鐵鐵,實(shí)際開發(fā)不管是公司要求或是自身發(fā)展,學(xué)前端已經(jīng)是我們內(nèi)卷路上必定碰到的,那今天小編就給大家總結(jié)下那些我們工作中可能遇到的一些實(shí)用Js函數(shù)2022-06-06
使用dynatrace-ajax跟蹤JavaScript的性能
DynaTrace 致力于分析后臺(tái)應(yīng)用性能的表現(xiàn)已經(jīng)好幾年了,最近,他們通過(guò)發(fā)布dynaTrace Ajax Edition進(jìn)入了前端性能分析領(lǐng)域. 它是一個(gè)運(yùn)行在IE下的BHO免費(fèi)工具. 雖然我喜歡Firefox和它下面的所有插件,但我知道基于IE的測(cè)試和調(diào)試也是很重要的。2010-04-04
js操作Xml(向服務(wù)器發(fā)送Xml,處理服務(wù)器返回的Xml)(IE下有效)
js操作Xml(向服務(wù)器發(fā)送Xml,處理服務(wù)器返回的Xml)(暫只IE下有效)2009-01-01
javascript元素動(dòng)態(tài)創(chuàng)建實(shí)現(xiàn)方法
這篇文章主要介紹了javascript元素動(dòng)態(tài)創(chuàng)建實(shí)現(xiàn)方法,涉及javascript操作元素的相關(guān)技巧,需要的朋友可以參考下2015-05-05

