微信公众号推送模板消息工具类

微信公众平台:

    开通 模板消息功能 ;

    添加消息模板;

    将模板id复制作为后台参数;

 

后台(java):

使用时直接调用WechatModelMessage.sendWechatmsgToUser() 即可,参数说明见sendWechatmsgToUser()方法的注释

测试方法:

public class Test{

    public static void main(String[] args) {
		WechatModelMessage.sendWechatmsgToUser("这里是用户的openId",
				"这里写微信公众平台模板的id", 
				"http://www.baidu.com", //跳转链接
				"#173177",//颜色
				MessageModel.packJsonmsg("这是第一行说明", "这是学生姓名", "这是类型", "这是日期", "这是最后一行备注"));//调用消息模板方法
	}
}

1.WechatModelMessage.java 主要类

/**
 * 发送微信模板消息
 * @author xujunkai
 *
 */
public class WechatModelMessage {

	// 获取access_token的接口地址(GET) 限200(次/天)
	public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";


	/**
	 * @method sendWechatmsgToUser
	 * @描述: TODO(发送模板信息给用户)
	 * @参数@param touser 用户的openid
	 * @参数@param templat_id 信息模板id
	 * @参数@param url 用户点击详情时跳转的url
	 * @参数@param topcolor 模板字体的颜色
	 * @参数@param data 模板详情变量 Json格式
	 * @参数@return
	 * @返回类型:String
	 * @添加时间 2018-9-27 15:38:54 
	 */
	public static String sendWechatmsgToUser(String touser, String templat_id, String clickurl, String topcolor,
			JSONObject data,Context ctx) {
		String tmpurl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
		WechatModelMessage wechatModelMessage = new WechatModelMessage();
		AccessToken accessToken = wechatModelMessage.getAccessToken(ctx);
		String token = accessToken.getToken(); // 微信凭证,access_token
		String url = tmpurl.replace("ACCESS_TOKEN", token);
		JSONObject json = new JSONObject();
		try {
			json.put("touser", touser);
			json.put("template_id", templat_id);
			json.put("url", clickurl);
			json.put("topcolor", topcolor);
			json.put("data", data);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		try {

			int i = 1;
			while (i <= 3) {// 循环发送3次
				JSONObject resultJson = WechatModelMessage.httpRequest(url, "POST", json.toString());
				String errmsg = (String) resultJson.get("errmsg");
				if ("ok".equals(errmsg)) { // 如果为errmsg为ok,则代表发送成功,公众号推送信息给用户了。
					i = 4;
					return "error";
				}else{
					System.out.println("***************************微信返回的错误信息:" + errmsg);
					i++;
				}
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return "success";
	}

	/**
	 * @描述: TODO(获取access_token)
	 * 
	 * @param appid  凭证
	 * @param appsecret  **
	 * @return
	 */
	public  AccessToken getAccessToken(Context ctx) {  
		AccessToken accessToken = null; 
		WebChatConfigModel weCharById =null;
        //以下是用jdbc查库,也可以用mybatis 目的取出微信配置表中的appId 和 appsecret 
		String sql="select * from T_SYS_WebChatConfig where fid=1";
		try {
			IRowSet rs=DbUtil.executeQuery(ctx, sql);
		if(rs.size()>0){
			while(rs.next()){
				weCharById=new WebChatConfigModel();
				weCharById.setCorpOrAppId(rs.getString("FCORPORAPPID"));
				weCharById.setCorpOrAppsecret(rs.getString("FCORPORAPPSECRET"));
			}
		}
		} catch (BOSException e1) {
			e1.printStackTrace();
		} catch (SQLException e1) {
			e1.printStackTrace();
		}
		//获取appId,appsecret
		String appId = weCharById.getCorpOrAppId();
		String appsecret = weCharById.getCorpOrAppsecret();
		System.out.println("***************************************appId="+appId); 
		System.out.println("***************************************appsecret="+appsecret); 
	    String requestUrl = access_token_url.replace("APPID", appId).replace("APPSECRET", appsecret);  
	    JSONObject jsonObject = httpRequest(requestUrl, "GET", null);  
	    // 如果请求成功  
	    if (null != jsonObject) {  
	        try {  
	            accessToken = new AccessToken();  
	            accessToken.setToken(jsonObject.getString("access_token"));  
	            accessToken.setExpiresIn(jsonObject.getInteger("expires_in"));  
	        } catch (JSONException e) {  
	            accessToken = null;  
	            // 获取token失败  
	            System.out.println("获取token失败 errcode:{"+jsonObject.getInteger("errcode")+"} errmsg:{"+jsonObject.getString("errmsg")+"}" );  
	        }  
	    }  
	    return accessToken;  
	}

	/**
	 * 
	 * @描述: TODO(发送http请求httpsRequest)
	 * @param requestUrl
	 * @param requestMethod
	 * @param outputStr
	 * @return
	 */
	public static JSONObject httpRequest(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.parseObject(buffer.toString());
		} catch (ConnectException ce) {
			System.out.println("************************Weixin server connection timed out.");
		} catch (Exception e) {
			System.out.println("************************https request error:{" + e + "}");
		}
		return jsonObject;
	}
}

2.MessageModel.java     将微信的消息模板需要的数据转为json,下面的方法对应截图模板

       后台json数据的key,必须与模板的形参名称一致(下图红框为形参)

微信公众号推送模板消息工具类

/**
 * 消息模板类
    每个消息模板对应一个方法,目的将数据封装成json
 * @author xujunkai
 *
 */
public class MessageModel {
	
	/**
	 * @method packJsonmsg
	 * @描述: TODO(封装微信模板:留学生活服务报告提醒)
	 * @参数@param first 头部
	 * @参数@param studentName 留学生名
	 * @参数@param typeName 报告类型
	 * @参数@param date 报告时间
	 * @参数@param remark 说明
	 * @参数@return
	 * @返回类型:JSONObject
	 * @添加时间 2018-9-27 15:38:54 
	 */
	public static JSONObject packJsonmsg(String first, String studentName, String typeName, String date,
			String remark) {
		JSONObject json = new JSONObject();
		try {
			JSONObject jsonFirst = new JSONObject();
			jsonFirst.put("value", first);
			jsonFirst.put("color", "#173177");
			json.put("first", jsonFirst);
			JSONObject jsonStudentName = new JSONObject();
			jsonStudentName.put("value", studentName);
			jsonStudentName.put("color", "#173177");
			json.put("keyword1", jsonStudentName);
			JSONObject JsonTypeName = new JSONObject();
			JsonTypeName.put("value", typeName);
			JsonTypeName.put("color", "#173177");
			json.put("keyword2", JsonTypeName);
			JSONObject jsonDate = new JSONObject();
			jsonDate.put("value", date);
			jsonDate.put("color", "#173177");
			json.put("keyword3", jsonDate);
			JSONObject jsonRemark = new JSONObject();
			jsonRemark.put("value", remark);
			jsonRemark.put("color", "#173177");
			json.put("remark", jsonRemark);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return json;
	}

}

3.AccessToken.java   Toke对象

public class AccessToken {

	private String token;
	private int expiresIn;
	public String getToken() {
		return token;
	}
	public void setToken(String token) {
		this.token = token;
	}
	public int getExpiresIn() {
		return expiresIn;
	}
	public void setExpiresIn(int expiresIn) {
		this.expiresIn = expiresIn;
	}
	
	
}

4.MyX509TrustManager.java   https请求的证书管理器

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;

/** 
 * 证书信任管理器(用于https请求) 
 *  
 */  
public class MyX509TrustManager implements X509TrustManager {  
  
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
    }  
  
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
    }  
  
    public X509Certificate[] getAcceptedIssuers() {  
        return null;  
    }  
}  

5、WebChatConfigModel.java  数据库微信配置模板表对应的对象

/**
	 * 对应于数据库的webchatconfig配置
	 * @author alfred
	 * 该数据配置不依赖于company和baseorg
	 * 由baseorg、company关联该对象
	 * 后期根据数据获取逻辑为先获取公司相关的微信账号,如果为空,这获取其上级组织的微信账号,如果还为空,则获取
	 * baseorg的微信账号,所以该实体的companyid、baseorgid为空
	 */

	public class WebChatConfigModel {
		private String id;
		//创建时间
		private Timestamp createTime;
		//最后修改时间
		private Timestamp lastupdateTime;
		//创建者
		private String creator;
		//最后修改者
		private String lastupdator;
		private String corpOrAppId; //企业Id 
		private String corpOrAppsecret; //管理组的凭证** 
		private String encodingAESKey;//加密的AESKEY
		private WebChatType chatType;//类型
									//最后一次访问的accessToken
		private String accessToken;	
		private String token;
		private String mch_id;
		private String notice_url;
		private String apiKey;
		private String pfxPath;//证书路径
		private String pfxPassword;//证书密码
			
		//Token最后一次创建时间
		private long tokenCreateTime;
		
		
		
		public String getId() {
			return id;
		}
		public void setId(String id) {
			this.id = id;
		}
		public String getCorpOrAppId() {
			return corpOrAppId;
		}
		public void setCorpOrAppId(String corpOrAppId) {
			this.corpOrAppId = corpOrAppId;
		}
		public String getCorpOrAppsecret() {
			return corpOrAppsecret;
		}
		public void setCorpOrAppsecret(String corpOrAppsecret) {
			this.corpOrAppsecret = corpOrAppsecret;
		}
		public String getEncodingAESKey() {
			return encodingAESKey;
		}
		public void setEncodingAESKey(String encodingAESKey) {
			this.encodingAESKey = encodingAESKey;
		}
		public WebChatType getChatType() {
			return chatType;
		}
		public void setChatType(WebChatType chatType) {
			this.chatType = chatType;
		}
		
		public String getAccessToken() {
			return accessToken;
		}
		public void setAccessToken(String accessToken) {
			this.accessToken = accessToken;
		}
		public String getToken() {
			return token;
		}
		public void setToken(String token) {
			this.token = token;
		}
		public long getTokenCreateTime() {
			return tokenCreateTime;
		}
		public void setTokenCreateTime(long tokenCreateTime) {
			this.tokenCreateTime = tokenCreateTime;
		}
		@Override
		public String toString() {
			StringBuilder sb=new StringBuilder();
			sb.append(chatType.toString()).append("-");
			sb.append(corpOrAppId).append("-");
			sb.append(corpOrAppsecret).append("-");
			sb.append(encodingAESKey);
			return sb.toString();
		}
		
		@Override
		public int hashCode() {
			int code=this.toString().hashCode();
			return code;
		}
		
		@Override
		public boolean equals(Object obj) {
			if(obj==null){
				return false;
			}
			if(obj.toString().equals(this.toString())){
				return true;
			}
			return false;
		}
		public String getMch_id() {
			return mch_id;
		}
		public void setMch_id(String mch_id) {
			this.mch_id = mch_id;
		}
		public String getNotice_url() {
			return notice_url;
		}
		public void setNotice_url(String notice_url) {
			this.notice_url = notice_url;
		}
		public String getApiKey() {
			return apiKey;
		}
		public void setApiKey(String apiKey) {
			this.apiKey = apiKey;
		}
		public String getPfxPath() {
			return pfxPath;
		}
		public void setPfxPath(String pfxPath) {
			this.pfxPath = pfxPath;
		}
		public String getPfxPassword() {
			return pfxPassword;
		}
		public void setPfxPassword(String pfxPassword) {
			this.pfxPassword = pfxPassword;
		}
		public Timestamp getCreateTime() {
			return createTime;
		}
		public void setCreateTime(Timestamp createTime) {
			this.createTime = createTime;
		}
		public Timestamp getLastupdateTime() {
			return lastupdateTime;
		}
		public void setLastupdateTime(Timestamp lastupdateTime) {
			this.lastupdateTime = lastupdateTime;
		}
		public String getCreator() {
			return creator;
		}
		public void setCreator(String creator) {
			this.creator = creator;
		}
		public String getLastupdator() {
			return lastupdator;
		}
		public void setLastupdator(String lastupdator) {
			this.lastupdator = lastupdator;
		}

	}

6、微信配置表sql

CREATE TABLE
    T_SYS_WEBCHATCONFIG
    (
        FID VARCHAR2(44) NOT NULL,
        FCREATETIME TIMESTAMP(6),
        FLASTUPDATETIME TIMESTAMP(6),
        FCREATORID VARCHAR2(44),
        FLASTUPDATORID VARCHAR2(44),
        FCORPORAPPID VARCHAR2(80),
        FCORPORAPPSECRET VARCHAR2(80),
        FENCODINGAESKEY VARCHAR2(80),
        FCHATTYPE VARCHAR2(80),
        FACCESSTOKEN VARCHAR2(255),
        FTOKEN VARCHAR2(255),
        FMCHID VARCHAR2(255),
        FNOTICEURL VARCHAR2(255),
        FAPIKEY VARCHAR2(255),
        FPFXPATH VARCHAR2(255),
        FPFXPASSORD VARCHAR2(255),
        FTOKENCREATETIME LONG,
        PRIMARY KEY (FID)
    );