微信公众号开发之模板消息

微信公众号发送模板消息其实很简单,调用下面的这个工具类即可(这个工具类是我在网上找的。。。)。工具类主要用于调用微信发送模板消息的接口。
首先会获取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。

猜你喜欢

转载自blog.csdn.net/qq_37253891/article/details/84566190