java推送微信模板消息

/**
 * 注册成功,通知模板消息实体类
 */
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

你可能感兴趣的:(微信java开发)