您好,登錄后才能下訂單哦!
這篇文章主要講解了用java后端實(shí)現(xiàn)微信小程序訂閱消息開發(fā),內(nèi)容清晰明了,對(duì)此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會(huì)有幫助。
訂閱消息說(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ā)者慎用此功能
看完上述內(nèi)容,是不是對(duì)用java后端實(shí)現(xiàn)微信小程序訂閱消息開發(fā)有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。