JAVA微信公众号推送信息

package weixin.util;

import java.io.Serializable;
/*
*AccessToken 对象
*/
public class AccessToken implements Serializable {
    //获取到的凭证
    private String accessToken;
    //凭证有效时间,单位:秒
    private int expiresin;  
    /**
     * @return the accessToken
     */
    public String getAccessToken() {
        return accessToken;
    }
    /**
     * @param accessToken the accessToken to set
     */
    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }
    /**
     * @return the expiresin
     */
    public int getExpiresin() {
        return expiresin;
    }
    /**
     * @param expiresin the expiresin to set
     */
    public void setExpiresin(int expiresin) {
        this.expiresin = expiresin;
    }
    public AccessToken() {
        // TODO Auto-generated constructor stub
    }

}
package weixin.util;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;
/**
 * 微信请求 - 信任管理器
 */

public class MyX509TrustManager implements X509TrustManager{

    public MyX509TrustManager() {
        // TODO Auto-generated constructor stub
    }
      @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;
        }

}
package weixin.util;
/**
 * 模板详细信息 
 * 根据需求自己更改
 */
public class TemplateData {
    private String value;
    private String color;
    public TemplateData(String value,String color){
        this.value = value;
        this.color = color;
    }
    /**
     * @return the value
     */
    public String getValue() {
        return value;
    }
    /**
     * @param value the value to set
     */
    public void setValue(String value) {
        this.value = value;
    }
    /**
     * @return the color
     */
    public String getColor() {
        return color;
    }
    /**
     * @param color the color to set
     */
    public void setColor(String color) {
        this.color = color;
    }

}
package weixin.util;

import java.util.Map;

/**
 * 注册成功,通知模板消息实体类
 */
public class TemplateMessage {
    private String touser; //用户OpenID
    private String template_id; //模板消息ID
    private String url; //URL置空,在发送后,点模板消息进入一个空白页面(ios),或无法点击(android)。
    private String topcolor; //标题颜色
    private Map templateData; //模板详细信息

    public static TemplateMessage New() {
        return new TemplateMessage();
    }

    /**
     * @return the touser
     */
    public String getTouser() {
        return touser;
    }
    /**
     * @param touser the touser to set
     */
    public void setTouser(String touser) {
        this.touser = touser;
    }
    /**
     * @return the template_id
     */
    public String getTemplate_id() {
        return template_id;
    }
    /**
     * @param template_id the template_id to set
     */
    public void setTemplate_id(String template_id) {
        this.template_id = template_id;
    }
    /**
     * @return the url
     */
    public String getUrl() {
        return url;
    }
    /**
     * @param url the url to set
     */
    public void setUrl(String url) {
        this.url = url;
    }
    /**
     * @return the topcolor
     */
    public String getTopcolor() {
        return topcolor;
    }
    /**
     * @param topcolor the topcolor to set
     */
    public void setTopcolor(String topcolor) {
        this.topcolor = topcolor;
    }
    /**
     * @return the templateData
     */
    public Map getTemplateData() {
        return templateData;
    }
    /**
     * @param templateData the templateData to set
     */
    public void setTemplateData(Map templateData) {
        this.templateData = templateData;
    }



}
package weixin.util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;

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;
    }

}
package weixin.util;

import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;

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";
   }

}
package weixin.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;


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() {

            String appId="wxfb36eac9d8bwe23q";  
            String appSecret="bf1as96d3e5af6be50464fcd2eba1413";
            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);
                System.out.println("jsonObject:"+jsonObject);
                AccessToken access_token = new AccessToken();
                if (null != jsonObject) {
                    try {
                        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"));
                    }
                }

            return access_token;
        }

}
package weixin.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;

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;
        }
}
package weixin.util;

import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;


public class TestWX {
    public static void main(String[] args) {
        //新增用户成功 - 推送微信消息
        senMsg("oYpZz1LHPO5qggb5tfiWdDDh7lCQ");
    }
   static void senMsg(String openId){
        //用户是否订阅该公众号标识 (0代表此用户没有关注该公众号 1表示关注了该公众号)
        Integer  state= WX_UserUtil.subscribeState(openId);
        System.out.println("state:"+state);
        // 绑定了微信并且关注了服务号的用户 , 注册成功-推送注册短信
        if(state==1){
            Map param = new HashMap<>();
            param.put("first",new TemplateData("恭喜其小林!","#696969"));
            param.put("keyword1",new TemplateData("12345345456","#696969"));
            param.put("keyword2",new TemplateData("2017年","#696969"));
            param.put("remark",new TemplateData("祝愉快!","#696969"));
            //注册的微信-模板Id
           // String regTempId =  WX_TemplateMsgUtil.getWXTemplateMsgId("ywBb70467vr18");

            JSON.toJSONString(param);
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(param));
            //调用发送微信消息给用户的接口
          WX_TemplateMsgUtil.sendWechatMsgToUser(openId,"veNLgN8mi-L3Gn67PfkO6l-yS42CV7m8T0c4Pf-PjFw", "", 
                  "#000000", jsonObject);


          //获取公众号的自动回复规则
          String urlinfo="https://api.weixin.qq.com/cgi-bin/get_current_autoreply_info?access_token="+WX_TokenUtil.getWXToken().getAccessToken();
          JSONObject joinfo = WX_HttpsUtil.httpsRequest(urlinfo, "GET", null);
          Object o=joinfo.get("is_add_friend_reply_open");
         // System.out.println("o:"+joinfo);
          String getTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
            JSONObject Token = WX_HttpsUtil.httpsRequest(getTokenUrl, "GET", null);
            System.out.println("Token:"+Token);


        }
    }

}

-----------------------
和微信交互servlet


package weixin.util.wxservlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class WxServlet extends HttpServlet{

    public WxServlet() {
        // TODO Auto-generated constructor stub
    }

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 微信加密签名  
        String signature = request.getParameter("signature");  
        // 时间戳  
        String timestamp = request.getParameter("timestamp");  
        // 随机数  
        String nonce = request.getParameter("nonce");  
        // 随机字符串  
        String echostr = request.getParameter("echostr");  

        PrintWriter out = response.getWriter();  
        // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败  
        if (SignUtil.checkSignature(signature, timestamp, nonce)) {  
            out.print(echostr);  
        }  
        out.close();  
        out = null;  
    }

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doPost(req, resp);
    }

}








package weixin.util.wxservlet;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/**
 * 请求校验工具类
 * @author m
 *
 */
public class SignUtil {
    // 与接口配置信息中的Token要一致  
    private static String token = "weixin";  

    /** 
     * 验证签名 
     *  
     * @param signature 
     * @param timestamp 
     * @param nonce 
     * @return 
     */  
    public static boolean checkSignature(String signature, String timestamp, String nonce) {  
        String[] arr = new String[] { token, timestamp, nonce };  
        // 将token、timestamp、nonce三个参数进行字典序排序  
        Arrays.sort(arr);  
        StringBuilder content = new StringBuilder();  
        for (int i = 0; i < arr.length; i++) {  
            content.append(arr[i]);  
        }  
        MessageDigest md = null;  
        String tmpStr = null;  

        try {  
            md = MessageDigest.getInstance("SHA-1");  
            // 将三个参数字符串拼接成一个字符串进行sha1加密  
            byte[] digest = md.digest(content.toString().getBytes());  
            tmpStr = byteToStr(digest);  
        } catch (NoSuchAlgorithmException e) {  
            e.printStackTrace();  
        }  

        content = null;  
        // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信  
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;  
    }  

    /** 
     * 将字节数组转换为十六进制字符串 
     *  
     * @param byteArray 
     * @return 
     */  
    private static String byteToStr(byte[] byteArray) {  
        String strDigest = "";  
        for (int i = 0; i < byteArray.length; i++) {  
            strDigest += byteToHexStr(byteArray[i]);  
        }  
        return strDigest;  
    }  

    /** 
     * 将字节转换为十六进制字符串 
     *  
     * @param mByte 
     * @return 
     */  
    private static String byteToHexStr(byte mByte) {  
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };  
        char[] tempArr = new char[2];  
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];  
        tempArr[1] = Digit[mByte & 0X0F];  

        String s = new String(tempArr);  
        return s;  
    }  
}




你可能感兴趣的:(java)