微信公眾號開發之模板訊息
阿新 • • 發佈:2018-12-19
微信公眾號傳送模板訊息其實很簡單,呼叫下面的這個工具類即可(這個工具類是我在網上找的。。。)。工具類主要用於呼叫微信傳送模板訊息的介面。
首先會獲取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。