/**
* 注册成功,通知模板消息实体类
*/
public class TemplateMessage {
private String touser; //用户OpenID
private String template_id; //模板消息ID
private String url; //URL置空,在发送后,点模板消息进入一个空白页面(ios),或无法点击(android)。
private String topcolor; //标题颜色
private Map templateData; //模板详细信息
//此处省略get/set 方法
}
/**
* 模板详细信息
*/
public class TemplateData {
private String value;
private String color;
public TemplateData(String value,String color){
this.value = value;
this.color = color;
}
//此处省略get/set 方法
}
/*
*AccessToken 对象
*/
public class AccessToken implements Serializable{
//获取到的凭证
private String accessToken;
//凭证有效时间,单位:秒
private int expiresin;
//此处省略get/set 方法
}
/**
* 微信请求 - 信任管理器
*/
public class MyX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
// return new X509Certificate[0];
return null;
}
}
/**
* 微信枚举
* /
public class WeiXinEnum {
// 缓存类型
public enum CACHE_TYPE {
CACHE_WX_ACCESS_TOKEN, //模板消息access_token
}
// 模板消息编号
public enum WX_TEMPLATE_MSG_NUMBER{
USER_REGISTER_SUCCESS(0,"OPENTM407796225", "注册成功"),
ORDER_PAYED_SUCCESS(1, "OPENTM207421553","订单支付"),
ORDER_...;
private int code;
private String msgNumber;
private String label;
WX_TEMPLATE_MSG_NUMBER(int code, String msgNumber,String label){
this.code = code;
this.msgNumber = msgNumber;
this.label = label;
}
public int getCode(){
return code;
}
public String getMsgNumber(){
return msgNumber;
}
public String getLabel(){
return label;
}
}
}
import com.alibaba.fastjson.JSONObject;
import com.qyuedai.crm.weixin.vo.MyX509TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
public class WX_HttpsUtil {
private static Logger log = LoggerFactory.getLogger(WX_HttpsUtil.class);
/**
* 发送https请求
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
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 conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);
// 当outputStr不为null时向输出流写数据
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
// 注意编码格式
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 从输入流读取返回内容
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
// 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
jsonObject = JSONObject.parseObject(buffer.toString());
} catch (ConnectException ce) {
log.error("连接超时:{}", ce);
} catch (Exception e) {
log.error("https请求异常:{}", e);
}
return jsonObject;
}
}
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.qyuedai.common.redis.Redis;
import com.qyuedai.crm.weixin.vo.AccessToken;
import com.qyuedai.crm.weixin.vo.WeiXinEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WX_TokenUtil {
private static Logger log = LoggerFactory.getLogger(WX_TokenUtil.class);
/**
* 获得微信 AccessToken
* access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。
* 开发者需要access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取
* 的access_token失效。
* (此处我是把token存在Redis里面了)
*/
public static AccessToken getWXToken() {
AccessToken access_token = Redis.getInstance().get(WeiXinEnum.CACHE_TYPE.CACHE_WX_ACCESS_TOKEN.name());
if(access_token == null || access_token.getAccessToken().equals("")){
String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appId+"&secret="+ appSecret;
JSONObject jsonObject = WX_HttpsUtil.httpsRequest(tokenUrl, "GET", null);
if (null != jsonObject) {
try {
access_token = new AccessToken();
access_token.setAccessToken(jsonObject.getString("access_token"));
access_token.setExpiresin(jsonObject.getInteger("expires_in"));
} catch (JSONException e) {
access_token = null;
// 获取token失败
log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
}
}
Redis.getInstance().set(WeiXinEnum.CACHE_TYPE.CACHE_WX_ACCESS_TOKEN.name(), access_token,7100);
}
return access_token;
}
}
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WX_UserUtil {
private static Logger log = LoggerFactory.getLogger(WX_UserUtil.class);
/**
* 根据微信openId 获取用户是否订阅
* @param openId 微信openId
* @return 是否订阅该公众号标识
*/
public static Integer subscribeState(String openId){
String tmpurl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+WX_TokenUtil.getWXToken().getAccessToken() +"&openid="+openId;
JSONObject result = WX_HttpsUtil.httpsRequest(tmpurl, "GET",null);
JSONObject resultJson = new JSONObject(result);
log.error("获取用户是否订阅 errcode:{} errmsg:{}", resultJson.getInteger("errcode"), resultJson.getString("errmsg"));
String errmsg = (String) resultJson.get("errmsg");
if(errmsg==null){
//用户是否订阅该公众号标识(0代表此用户没有关注该公众号 1表示关注了该公众号)。
Integer subscribe = (Integer) resultJson.get("subscribe");
return subscribe;
}
return -1;
}
}
import com.alibaba.fastjson.JSONObject;
import com.qyuedai.crm.weixin.vo.TemplateData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
public class WX_TemplateMsgUtil {
private static Logger log = LoggerFactory.getLogger(WX_TemplateMsgUtil.class);
/**
* 封装模板详细信息
* @return
*/
public static JSONObject packJsonmsg(Map param) {
JSONObject json = new JSONObject();
for (Map.Entry entry : param.entrySet()) {
JSONObject keyJson = new JSONObject();
TemplateData dta= entry.getValue();
keyJson.put("value",dta.getValue());
keyJson.put("color", dta.getColor());
json.put(entry.getKey(), keyJson);
}
return json;
}
/**
* 根据模板的编号 新增并获取模板ID
* @param templateSerialNumber 模板库中模板的 "编号"
* @return 模板ID
*/
public static String getWXTemplateMsgId(String templateSerialNumber){
String tmpurl = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token="+ WX_TokenUtil.getWXToken().getAccessToken();
JSONObject json = new JSONObject();
json.put("template_id_short", templateSerialNumber);
JSONObject result = WX_HttpsUtil.httpsRequest(tmpurl, "POST", json.toString());
JSONObject resultJson = new JSONObject(result);
String errmsg = (String) resultJson.get("errmsg");
log.info("获取模板编号返回信息:" + errmsg);
if(!"ok".equals(errmsg)){
return "error";
}
String templateId = (String) resultJson.get("template_id");
return templateId;
}
/**
* 根据模板ID 删除模板消息
* @param templateId 模板ID
* @return
*/
public static String deleteWXTemplateMsgById(String templateId){
String tmpurl = "https://api.weixin.qq.com/cgi-bin/template/del_private_template?access_token="+ WX_TokenUtil.getWXToken().getAccessToken();
JSONObject json = new JSONObject();
json.put("template_id", templateId);
try{
JSONObject result = WX_HttpsUtil.httpsRequest(tmpurl, "POST", json.toString());
JSONObject resultJson = new JSONObject(result);
log.info("删除"+templateId+"模板消息,返回CODE:"+ resultJson.get("errcode"));
String errmsg = (String) resultJson.get("errmsg");
if(!"ok".equals(errmsg)){
return "error";
}
}catch(Exception e){
e.printStackTrace();
}
return "success";
}
/**
* 发送微信消息(模板消息)
* @param touser 用户 OpenID
* @param templatId 模板消息ID
* @param clickurl URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。
* @param topcolor 标题颜色
* @param data 详细内容
* @return
*/
public static String sendWechatMsgToUser(String touser, String templatId, String clickurl, String topcolor, JSONObject data) {
String tmpurl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+ WX_TokenUtil.getWXToken().getAccessToken();
JSONObject json = new JSONObject();
json.put("touser", touser);
json.put("template_id", templatId);
json.put("url", clickurl);
json.put("topcolor", topcolor);
json.put("data", data);
try{
JSONObject result = WX_HttpsUtil.httpsRequest(tmpurl, "POST", json.toString());
JSONObject resultJson = new JSONObject(result);
log.info("发送微信消息返回信息:" + resultJson.get("errcode"));
String errmsg = (String) resultJson.get("errmsg");
if(!"ok".equals(errmsg)){ //如果为errmsg为ok,则代表发送成功,公众号推送信息给用户了。
return "error";
}
}catch(Exception e){
e.printStackTrace();
return "error";
}finally {
if(templatId!=null) {
//删除新增的 微信模板
deleteWXTemplateMsgById(templatId);
}
}
return "success";
}
}
import com.qyuedai.crm.weixin.util.WX_TemplateMsgUtil;
import com.qyuedai.crm.weixin.util.WX_UserUtil;
import com.qyuedai.crm.weixin.vo.TemplateData;
import com.qyuedai.crm.weixin.vo.WeiXinEnum;
import java.util.HashMap;
import java.util.Map;
import static com.qyuedai.crm.weixin.util.WX_TemplateMsgUtil.getWXTemplateMsgId;
import static com.qyuedai.crm.weixin.util.WX_TemplateMsgUtil.packJsonmsg;
public class Test {
public static void main(String[] args) {
//新增用户成功 - 推送微信消息
senMsg("oUBBZwTa7qxb0vP98X8WhAazdvUE");
}
static void senMsg(String openId){
//用户是否订阅该公众号标识 (0代表此用户没有关注该公众号 1表示关注了该公众号)
Integer state= WX_UserUtil.subscribeState(openId);
// 绑定了微信并且关注了服务号的用户 , 注册成功-推送注册短信
if(state==1){
Map param = new HashMap<>();
param.put("first",new TemplateData("恭喜您注册成功!","#696969"));
param.put("keyword1",new TemplateData("15618551533","#696969"));
param.put("keyword2",new TemplateData("2017年05月06日","#696969"));
param.put("remark",new TemplateData("祝投资愉快!","#696969"));
//注册的微信-模板Id
String regTempId = getWXTemplateMsgId(WeiXinEnum.WX_TEMPLATE_MSG_NUMBER.USER_REGISTER_SUCCESS.getMsgNumber());
//调用发送微信消息给用户的接口
WX_TemplateMsgUtil.sendWechatMsgToUser(openId,regTempId, "", "#000000", packJsonmsg(param));
}
}
}
其他消息模板请参考 微信服务号 - 模板消息-模板库 里面的消息模板。
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183&token=&lang=zh_CN