1. 程式人生 > >微信公眾號開發之模板訊息

微信公眾號開發之模板訊息

微信公眾號傳送模板訊息其實很簡單,呼叫下面的這個工具類即可(這個工具類是我在網上找的。。。)。工具類主要用於呼叫微信傳送模板訊息的介面。
首先會獲取ACCESS_TOKEN,若之前獲取的沒過期則用之前的,若過期了則從新獲取。然後用一個http工具類呼叫傳送模板訊息的介面即可。
傳送模板訊息工具類:

package org.guangyu.utils;

import java.io.IOException;
import java.util.Date;
import java.util.Properties;

import net.sf.json.JSONObject;

public class WeChatUtil {
	// // URL驗證時使用的token
	// public static final String TOKEN = "qq";
	// appid
	public static String APPID = "";
	// secret
	public static String SECRET = "";
	// 建立選單介面地址
	// public static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
	// 傳送模板訊息的介面
	public static final String SEND_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
	// 獲取access_token的介面地址
	public static final String GET_ACCESSTOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	// 快取的access_token
	private static String accessToken;
	// access_token的失效時間
	private static long expiresTime;
	
	private static Properties properties = new Properties();

	
	static{
	    try {
	        properties.load(WeChatUtil.class.getClassLoader().getResourceAsStream("weixin.properties"));
	        APPID = properties.getProperty("APPID");
	        SECRET = properties.getProperty("SECRET");
	    } catch (IOException e) {
	        e.printStackTrace();
        }
	}
	
	/**
	 * 獲取accessToken
	 * 
	 * @return
	 * @throws IOException
	 */
	public static String getAccessToken() throws IOException {
		// 判斷accessToken是否已經過期,如果過期需要重新獲取
		if (accessToken == null || expiresTime < new Date().getTime()) {
			// 發起請求獲取accessToken
			String result = HttpUtil.get(GET_ACCESSTOKEN_URL.replace("APPID",
					APPID).replace("APPSECRET", SECRET));
			System.out.println(APPID + "/////" + SECRET);
			// 把json字串轉換為json物件
			JSONObject json = JSONObject.fromObject(result);
			// 快取accessToken
			accessToken = json.getString("access_token");
			// 設定accessToken的失效時間
			long expires_in = json.getLong("expires_in");
			// 失效時間 = 當前時間 + 有效期(提前一分鐘)
			expiresTime = new Date().getTime() + (expires_in - 60) * 1000;
		}
		return accessToken;
	}

	/**
	 * 傳送模板
	 * 
	 * @return 結果集({"errcode":0,"errmsg":"ok","msgid":528986890112614400})、
	 * 				({"errcode":40003,"errmsg":"invalid openid hint: [tv6YMa03463946]"})
	 * @throws IOException
	 */
	public static String sendTemplate(String data) throws IOException {
		// 通過呼叫HttpUtil工具類傳送post請求
		// 呼叫微信傳送模板訊息的介面
		String result = HttpUtil.post(SEND_TEMPLATE_URL.replace("ACCESS_TOKEN",
				getAccessToken()), data);
		System.out.println(result);
		return result;
	}
}

weixin.properties是配置檔案。用於動態獲取APPID和APPSECRET。

APPID=xxxxxxxx
SECRET=xxxxxxxxxxxxxxxxxxxxxx

至於HttpUtil是一個http工具類,網上有很多。

package org.guangyu.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * @project baidamei
 * @author cevencheng <
[email protected]
> * @create 2012-11-17 ����2:35:38 */ public class HttpUtil { /** * Send a get request * * @param url * @return response * @throws IOException */ static public String get(String url) throws IOException { return get(url, null); } /** * Send a get request * * @param url * Url as string * @param headers * Optional map with headers * @return response Response as string * @throws IOException */ static public String get(String url, Map<String, String> headers) throws IOException { return fetch("GET", url, null, headers); } /** * Send a post request * * @param url * Url as string * @param body * Request body as string * @param headers * Optional map with headers * @return response Response as string * @throws IOException */ static public String post(String url, String body, Map<String, String> headers) throws IOException { return fetch("POST", url, body, headers); } /** * Send a post request * * @param url * Url as string * @param body * Request body as string * @return response Response as string * @throws IOException */ static public String post(String url, String body) throws IOException { return post(url, body, null); } /** * Post a form with parameters * * @param url * Url as string * @param params * map with parameters/values * @return response Response as string * @throws IOException */ static public String postForm(String url, Map<String, String> params) throws IOException { return postForm(url, params, null); } /** * Post a form with parameters * * @param url * Url as string * @param params * Map with parameters/values * @param headers * Optional map with headers * @return response Response as string * @throws IOException */ static public String postForm(String url, Map<String, String> params, Map<String, String> headers) throws IOException { // set content type if (headers == null) { headers = new HashMap<String, String>(); } headers.put("Content-Type", "application/x-www-form-urlencoded"); // parse parameters String body = ""; if (params != null) { boolean first = true; for (String param : params.keySet()) { if (first) { first = false; } else { body += "&"; } String value = params.get(param); body += URLEncoder.encode(param, "UTF-8") + "="; body += URLEncoder.encode(value, "UTF-8"); } } return post(url, body, headers); } /** * Send a put request * * @param url * Url as string * @param body * Request body as string * @param headers * Optional map with headers * @return response Response as string * @throws IOException */ static public String put(String url, String body, Map<String, String> headers) throws IOException { return fetch("PUT", url, body, headers); } /** * Send a put request * * @param url * Url as string * @return response Response as string * @throws IOException */ static public String put(String url, String body) throws IOException { return put(url, body, null); } /** * Send a delete request * * @param url * Url as string * @param headers * Optional map with headers * @return response Response as string * @throws IOException */ static public String delete(String url, Map<String, String> headers) throws IOException { return fetch("DELETE", url, null, headers); } /** * Send a delete request * * @param url * Url as string * @return response Response as string * @throws IOException */ static public String delete(String url) throws IOException { return delete(url, null); } /** * Append query parameters to given url * * @param url * Url as string * @param params * Map with query parameters * @return url Url with query parameters appended * @throws IOException */ static public String appendQueryParams(String url, Map<String, String> params) throws IOException { String fullUrl = new String(url); if (params != null) { boolean first = (fullUrl.indexOf('?') == -1); for (String param : params.keySet()) { if (first) { fullUrl += '?'; first = false; } else { fullUrl += '&'; } String value = params.get(param); fullUrl += URLEncoder.encode(param, "GBK") + '='; fullUrl += URLEncoder.encode(value, "GBK"); } } return fullUrl; } /** * Retrieve the query parameters from given url * * @param url * Url containing query parameters * @return params Map with query parameters * @throws IOException */ static public Map<String, String> getQueryParams(String url) throws IOException { Map<String, String> params = new HashMap<String, String>(); int start = url.indexOf('?'); while (start != -1) { // read parameter name int equals = url.indexOf('=', start); String param = ""; if (equals != -1) { param = url.substring(start + 1, equals); } else { param = url.substring(start + 1); } // read parameter value String value = ""; if (equals != -1) { start = url.indexOf('&', equals); if (start != -1) { value = url.substring(equals + 1, start); } else { value = url.substring(equals + 1); } } params.put(URLDecoder.decode(param, "GBK"), URLDecoder.decode( value, "GBK")); } return params; } /** * Returns the url without query parameters * * @param url * Url containing query parameters * @return url Url without query parameters * @throws IOException */ static public String removeQueryParams(String url) throws IOException { int q = url.indexOf('?'); if (q != -1) { return url.substring(0, q); } else { return url; } } /** * Send a request * * @param method * HTTP method, for example "GET" or "POST" * @param url * Url as string * @param body * Request body as string * @param headers * Optional map with headers * @return response Response as string * @throws IOException */ static public String fetch(String method, String url, String body, Map<String, String> headers) throws IOException { // connection URL u = new URL(url); HttpURLConnection conn = (HttpURLConnection) u.openConnection(); conn.setConnectTimeout(90000); conn.setReadTimeout(90000); // method if (method != null) { conn.setRequestMethod(method); } // headers if (headers != null) { for (String key : headers.keySet()) { conn.addRequestProperty(key, headers.get(key)); } } // body if (body != null) { conn.setDoOutput(true); OutputStream os = conn.getOutputStream(); os.write(body.getBytes("UTF-8")); os.flush(); os.close(); } // response InputStream is = conn.getInputStream(); String response = streamToString(is); is.close(); // handle redirects if (conn.getResponseCode() == 301) { String location = conn.getHeaderField("Location"); return fetch(method, location, body, headers); } return response; } /** * Read an input stream into a string * * @param in * @return * @throws IOException */ static public String streamToString(InputStream in) throws IOException { StringBuffer out = new StringBuffer(); byte[] b = new byte[4096]; for (int n; (n = in.read(b)) != -1;) { out.append(new String(b, 0, n)); } return out.toString(); } }

做完以上準備,接下來就開始來正式的了。
在這裡插入圖片描述這是官網上說的一些引數。
接下來編寫一個實體類用於存放這些引數。

package org.guangyu.orm.model;

import java.util.TreeMap;

public class TemplateMessage {
	private String touser; // 接收者openid

	private String template_id; // 模板ID

	private String url; // 模板跳轉連結

	private TreeMap<String, TreeMap<String, String>> data; // data資料

	//get、set已省略

	/**
	 * 引數
	 * 
	 * @param value
	 * @param color
	 *            可不填
	 * @return
	 */
	public static TreeMap<String, String> item(String value, String color) {
		TreeMap<String, String> params = new TreeMap<String, String>();
		params.put("value", value);
		params.put("color", color);
		return params;
	}
}

然後再呼叫:

public void sendTemplateMessage() throws IOException {
	System.out.println("開始封裝模板訊息。。。。。。。。。。");
	// 將資訊內容封裝到實體類
	TemplateMessage temp = new TemplateMessage();
	// 設定接收方的openid		user.getOpenid()是從資料庫中得到的對應的openid
	temp.setTouser(user.getOpenid());
	// 設定模板id(從頁面上覆制)
	temp.setTemplate_id("VMFMaNyr67yn8dMk1UJPwS1yTLgPUDHZbBj9D608O0c");
	// 設定回撥地址(點選模板訊息所跳轉的地址,設定為空即無跳轉)
	temp.setUrl("");
	// 設定模板訊息內容和對應的字型顏色
	TreeMap<String, TreeMap<String, String>> params = new TreeMap<String, TreeMap<String, String>>();
	params.put("first", TemplateMessage.item("新的學習任務已釋出,請登入APP儘快完成,完成任務得紅包!", "#173177"));
	//date為當前時間,new出來的在這裡省略
	params.put("keyword1", TemplateMessage.item(date, "#173177"));
	params.put("keyword2", TemplateMessage.item("尚未完成!", "#173177"));
	params.put("keyword3", TemplateMessage.item("-", "#173177"));
	params.put("remark", TemplateMessage.item("", "#173177"));
	// 將實體類轉為jsonObject
	JSONObject data = JSONObject.fromObject(temp);
	System.out.println(data + "");
	// 通過工具類呼叫微信介面傳送模板訊息
	String result = WeChatUtil.sendTemplate(data + "");
	System.out.println("返回結果集:" + result);
}

結果如下圖所示:
在這裡插入圖片描述
沒設定url即為不可點選,設定了則點選即可跳轉到設定的url。