springboot項目之小程序推送

該篇文章主要講的是後臺如何對小程序登錄的用戶進行通知。

ps:由於開發時間和寫文章時間間隔過久,細節上的可能不是很詳細,但是會把整體功能,以及代碼實現貼上來。
通知效果:
在這裏插入圖片描述
解釋: 簡單的說就是用戶登陸過小程序那便可以,將自己想要推送的內容發送到用戶的微信當中,微信當中有一個叫服務通知的東西,推送的內容會在上面顯示。
上面這種消息模板是在微信公衆平臺–>功能–>模板消息下面配置的,具體模板顯示內容可以調整。

1. 推送必須的東西
在這裏插入圖片描述
首先呢這兩個一個叫小程序Id一個叫小程序密鑰這兩個是可以在微信公衆平臺查到的。
接下來有三個url這個是發送推送消息必不可少的,第一個url是獲取小程序全局唯一後臺接口調用憑據;第二個接口是微信小程序推送接口,第三個接口是簡單講就是獲取openId。然後微信開發者公衆平臺開發接口目錄如下:微信公衆平臺開放接口

//獲取access_token
private final static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&";
//推送url
private final static String PUSH_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=";
//根據code換取openId
//本接口應在後端服務器調用
private final static String CODE_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=";

以上這5個算是準備工作吧,然後接下來就是正式進入推送了。

2. 首先我們創建一個獲取openId的工具類
根據官方文檔和摸索一下,這個獲取openId還是很簡單的。
官方上的解釋是: 登錄憑證校驗。通過 wx.login() 接口獲得臨時登錄憑證 code 後傳到開發者服務器調用此接口完成登錄流程。
也就是說上面說的第三個接口,通過把code傳遞到後臺,然後通過後臺調用第三個接口,便可以獲取我們想得到接口,具體代碼如下:

//獲取小程序codeid換取openid
	public static String getOpenId(String codeId) {
		String url = CODE_URL + APP_ID + "&secret=" + SECRET + "&js_code=" + codeId + "&grant_type=authorization_code";
		PrintWriter out = null;
		BufferedReader in = null;
		String line;
		StringBuffer sb = new StringBuffer();
		try {
			URL realUrl = new URL(url);
			// 打開和URL之間的連接
			URLConnection conn = realUrl.openConnection();

			// 設置通用的請求屬性 設置請求格式
			//設置返回類型
			conn.setRequestProperty("contentType", "text/plain");
			//設置請求類型
			conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
			//設置超時時間
			conn.setConnectTimeout(1000);
			conn.setReadTimeout(1000);
			conn.setDoOutput(true);
			conn.connect();
			// 獲取URLConnection對象對應的輸出流
			out = new PrintWriter(conn.getOutputStream());
			// flush輸出流的緩衝
			out.flush();
			// 定義BufferedReader輸入流來讀取URL的響應    設置接收格式
			in = new BufferedReader(
					new InputStreamReader(conn.getInputStream(), "UTF-8"));
			while ((line = in.readLine()) != null) {
				sb.append(line);
			}
			JSONObject jsonObject = JSONObject.parseObject(sb.toString());
			return jsonObject.get("openid").toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		//使用finally塊來關閉輸出流、輸入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return null;
	}

這樣我們就換取用戶的唯一標識 openId,具體上面的代碼可以直接複用也比較簡單就不多囉嗦了。

3. 接下來呢我們就要獲取access_token(本接口應在後端服務器調用)
關於access_token的官方解釋: 獲取小程序全局唯一後臺接口調用憑據(access_token)。調用各後臺接口時都需使用 access_token,開發者需要進行妥善保存。
看官方的解釋我們不難理解,access_token是調用微信後臺接口比不可少的東西。注意事項官方也很明確的寫出來瞭如下:在這裏插入圖片描述
獲取access_token工具類如下:


public static JSONObject getAccessToken() {
		String url = ACCESS_TOKEN_URL + "appid=" + APP_ID + "&secret=" + SECRET;
		PrintWriter out = null;
		BufferedReader in = null;
		String line;
		StringBuffer sb = new StringBuffer();
		try {
			URL realUrl = new URL(url);
			// 打開和URL之間的連接
			URLConnection conn = realUrl.openConnection();

			// 設置通用的請求屬性 設置請求格式
			//設置返回類型
			conn.setRequestProperty("contentType", "text/plain");
			//設置請求類型
			conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
			//設置超時時間
			conn.setConnectTimeout(1000);
			conn.setReadTimeout(1000);
			conn.setDoOutput(true);
			conn.connect();
			// 獲取URLConnection對象對應的輸出流
			out = new PrintWriter(conn.getOutputStream());
			// flush輸出流的緩衝
			out.flush();
			// 定義BufferedReader輸入流來讀取URL的響應    設置接收格式
			in = new BufferedReader(
					new InputStreamReader(conn.getInputStream(), "UTF-8"));
			while ((line = in.readLine()) != null) {
				sb.append(line);
			}
			// 將獲得的String對象轉爲JSON格式
			JSONObject jsonObject = JSONObject.parseObject(sb.toString());
			return jsonObject;
		} catch (Exception e) {
			e.printStackTrace();
		}
		//使用finally塊來關閉輸出流、輸入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return null;
	}

解釋已經很詳細了,最後再說一些細節的操作先把工具類放出來。

4.推送工具類 (本接口應在後端服務器調用)
推送的具體實現具體的參數啊,還是查看官方文檔再次不多贅述了。模板消息推送官方解釋
代碼如下:

/**
 * 推送工具類
 * @author 柚子
 * @date 2018/12/25
 * @param params 推送消息內容
 * @param accessToken 
 * @return boolean
 */
public static boolean setPush(String params, String accessToken) {
		boolean flag = false;
		String url = PUSH_URL + accessToken;
		OutputStream outputStream = null;
		InputStreamReader inputStreamReader = null;
		InputStream inputStream = null;
		BufferedReader bufferedReader = null;
		HttpsURLConnection connection = null;
		try {
			// 創建URL對象
			URL realUrl = new URL(url);
			// 打開連接 獲取連接對象
			connection = (HttpsURLConnection) realUrl.openConnection();
			// 設置請求編碼
			connection.addRequestProperty("encoding", "UTF-8");
			// 設置允許輸入
			connection.setDoInput(true);
			// 設置允許輸出
			connection.setDoOutput(true);
			connection.setRequestMethod("POST");
			connection.setRequestProperty("content-type", "application/x-www-form-urlencoded");
			// 當outputStr不爲null時向輸出流寫數據
			if (null != params) {
				outputStream = connection.getOutputStream();
				// 注意編碼格式
				outputStream.write(params.getBytes("UTF-8"));
				outputStream.close();
			}
			// 從輸入流讀取返回內容
			inputStream = connection.getInputStream();
			inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			JSONObject jsonObject = JSONObject.parseObject(buffer.toString());
			int errorCode = jsonObject.getInteger("errcode");
			String errorMessage = jsonObject.getString("errmsg");
			if (errorCode == 0) {
				flag = true;
			} else {
				logger.info("模板消息發送失敗:" + errorCode + "," + errorMessage);
				flag = false;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 依次關閉打開的輸入流
			try {
				connection.disconnect();
				bufferedReader.close();
				inputStreamReader.close();
				inputStream.close();
				// 依次關閉打開的輸出流
				outputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return flag;
	}

請求數據的示例在官網當中是有的,json形式的數據也就是對應params參數,accessToken參數我們是通過傳遞進來的當然也可以寫死。
5.最後的實現描述
關於推送的實現的描述:
代碼如下所示:

/**
	 * 功能描述
	 *
	 * @param openId     小程序openId
	 * @param formId     小程序formId
	 * @param title      通知標題
	 * @param content    通知內容
	 * @return boolean
	 * @author youzi
	 * @date 2018/12/14
	 */
	private boolean pushNoticeUtil(String openId, String formId, String title,String content) {
		logger.info("pushNoticeUtil方法開始");
		//緩存access_token
		if (redisUtils.get("access_token") == null || redisUtils.get("access_token").toString() == "") {
			JSONObject jsonObject = getAccessToken();
			if (jsonObject.get("expires_in") != null && jsonObject.get("expires_in").toString() != ""
					&& Integer.parseInt(jsonObject.get("expires_in").toString()) == 7200) {
				redisUtils.set("access_token", jsonObject.get("access_token"), 2 * 60 * 60L);
			}
		}
		JSONObject jsonObject1 = new JSONObject();
		jsonObject1.put("touser", openId);
		// DINING_TEMPLATE 模板Id  微信公衆平臺添加模板時生成的ID
		jsonObject1.put("template_id", DINING_TEMPLATE);
		jsonObject1.put("form_id", formId);
		JSONObject jsonObject2 = new JSONObject();
		JSONObject jsonObject3 = new JSONObject();
		jsonObject3.put("value", title);
		jsonObject2.put("keyword1", jsonObject3);
		jsonObject3 = new JSONObject();
		jsonObject3.put("value", content);
		jsonObject2.put("keyword2", jsonObject3);
		jsonObject1.put("data", jsonObject2);
		boolean pushResult = setPush(jsonObject1.toString(), redisUtils.get("access_token"));
		logger.info("pushNoticeUtil方法結束:推送結果" + pushResult);
		return pushResult;
	}

疑問: formId是什麼? 簡單的將就是小程序發送請求傳遞的一個東西,作用是用戶發送消息模板消息,具體的獲取官方文檔如下:獲取formId
只是簡單的解釋一下可能不是很清楚,但是隻要知道想要推送消息,那就必須要formId。
整體流程:
首先微信小程序登錄,登錄我們會獲取到openId,將其和自己後臺登錄綁定到一起這樣我們就可以保存下來openId用來推送,然後我們在小程序登錄的時候模擬發送請求獲取多個formId,將獲取到的formId和openId保存到數據庫表中,但是要注意formId是有時效性的如果時效了,推送也會推送不到用戶。
然後我們便可以準備推送了,推送時我們可以先獲取accessToken,將accessToken 放進redis裏面設置過期時間,如果過期了我們重新獲取,否則不需要重新獲取,官方的建議也是如此。然後組裝我們的推送數據,具體的組裝數據需要根據模板確定,但是形式上是一樣,然後調用推送此時便可以發現推送成功了。
最後: 如果還有疑問的話大家可以聯繫我,一起探討一下qq704273004,謝謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章