1. 程式人生 > 程式設計 >微信小程式訂閱訊息(java後端實現)開發

微信小程式訂閱訊息(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.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 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 outputStr) { 
  
 String result=""; 
 StringBuffer buffer = new StringBuffer(); 
 try { 
  // 建立SSLContext物件,並使用我們指定的信任管理器初始化 
  TrustManager[] tm = { new MyX509TrustManager() }; 
  SSLContext sslContext = SSLContext.getInstance("SSL","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後端實現)開發的文章就介紹到這了,更多相關小程式訂閱訊息內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!