java后台关联微信公众号开发

1.需要配置到微信公众号的法控制类

注意:get是用于微信公众号的校验哒
post是用来接收公众号发送的请求进行处理

package com.youruan.logistics.controller;

import com.youruan.logistics.config.global.Mark;
import com.youruan.logistics.util.MessageUtil;
import com.youruan.logistics.util.SignUtil;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Enumeration;
import com.youruan.logistics.entity.TemplateParam;
import com.youruan.logistics.entity.WxTemplate;
import com.youruan.logistics.util.HttpUtilOfWx;
import com.youruan.logistics.util.SendWxMessage;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("wechat")
public class WeChatController {
    private static Logger logger = Logger.getLogger(WeChatController.class);

    @RequestMapping(value = "/wx.do")
    public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {

        logger.info("WechatController   ----   WechatController");

        System.out.println("========WechatController========= ");
        logger.info("请求进来了...");

        Enumeration pNames = request.getParameterNames();
        while (pNames.hasMoreElements()) {
            String name = (String) pNames.nextElement();
            String value = request.getParameter(name);
            // out.print(name + "=" + value);

            String log = "name =" + name + "     value =" + value;
            logger.info(log);
        }

        String signature = request.getParameter("signature");/// 微信加密签名
        String timestamp = request.getParameter("timestamp");/// 时间戳
        String nonce = request.getParameter("nonce"); /// 随机数
        String echostr = request.getParameter("echostr"); // 随机字符串
        PrintWriter out = response.getWriter();

        if (SignUtil.checkSignature(signature, timestamp, nonce)) {
            out.print(echostr);
        }
        out.close();
        out = null;

    }
    @PostMapping(value = "/wx.do")
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws Exception,IOException {
        logger.info("接入成功,正在处理逻辑");
        //接受微信服务器发送过来的XML形式的消息
        InputStream in=request.getInputStream();
        BufferedReader reader=new BufferedReader(new InputStreamReader(in,"UTF-8"));
        String sReqData="";
        String itemStr="";//作为输出字符串的临时串,用于判断是否读取完毕
        while((itemStr=reader.readLine())!=null){
            sReqData+=itemStr;
        }
        in.close();
        reader.close();

        System.out.println("收到消息:"+sReqData);
        /*
        
        
        1565690913
        
        
        
         */
        //防止中文乱码
        response.setCharacterEncoding("UTF-8");
        MessageUtil.replyMessage(sReqData,response.getWriter());
        /*InputStream inputStream = request.getInputStream();
        Map params = XMLUtil.parseStreamToMap(inputStream);
        String respXml = messageHandleService.handleMessage(params);
        if (StringUtils.isNotEmpty(respXml)) {
            // 输出流
            response.getWriter().write(respXml);
        }*/

    }

    /**
     * 給用戶推送消息通知
     * 參數:用戶openId  物流實體
     * @return
     * @throws Exception
     */
    @PostMapping("test")
    public String updateById() throws Exception {
        //根据bid去查询出bos_customer中的数据
        /*Bos_customer customer=projectService.findCustomerByBid(bid);
        System.out.println("Bos_customer:"+customer.getCid()+"-------"+customer.getCname()+"-------"+customer.getOpenId());
        */
        //接下来给这个客户发送模板消息
        //先给模板中设置参数
        WxTemplate tem=new WxTemplate();
        tem.setTemplateId("Xk5hFStGRux8wP9Wqx45UR593LAOwYgoebi1oXVOcZA");  //模板id
        tem.setTopColor("#00DD00");
        tem.setToUser("o8ulT1hr9mAkR6i7-EI9vDr_lsio");//得到用户的openid
        tem.setUrl("");
        List paras=new ArrayList();
        paras.add(new TemplateParam("first","我们将给您推送一些关于您订单进度的消息:","#FF3333"));
        paras.add(new TemplateParam("keyword1","武汉物流有限公司","#0044BB"));//物流公司
        paras.add(new TemplateParam("keyword2","420115124541","#0044BB"));//物流单号
        paras.add(new TemplateParam("keyword3","武汉市","#0044BB"));//目的地
        paras.add(new TemplateParam("keyword4","待取件","#0044BB"));//物流状态
        paras.add(new TemplateParam("remark","感谢您的使用!!!!","#AAAAAA"));
        tem.setTemplateParamList(paras);
        //将Accesstoken拿到
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
        String APPID = Mark.GZH_APPID;
        String SECRET = Mark.GZH_APPSECRET;
        url = url.replace("APPID", APPID);
        url = url.replace("APPSECRET", SECRET);
        String content = HttpUtilOfWx.httpUrlConnect(url, null, "GET");
        System.out.println(content);
        Map map=HttpUtilOfWx.getAccessTokenByJsonStr(content);
        String accessToken=(String) map.get("access_token");
        System.out.println(accessToken);
        boolean result= SendWxMessage.sendTemplateMsg(accessToken,tem);
        if(result==true){
            System.out.println("发送成功");
        }

        return "redirect:showAll";
    }


}

2.MessageUtil

package com.youruan.logistics.util;

import com.alibaba.fastjson.JSONObject;
import com.youruan.logistics.config.excetion.ServiceException;
import com.youruan.logistics.config.global.Constant;
import com.youruan.logistics.config.global.Mark;
import org.dom4j.Document;
import org.dom4j.Element;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

public class MessageUtil {

    public static void replyMessage(String message, PrintWriter out) throws IOException {
        Document document = XMLUtil.readString2XML(message);
        Element root = document.getRootElement();
        String MsgType = XMLUtil.readNode(root, "MsgType");
        String ToUserName = XMLUtil.readNode(root, "ToUserName");   //开发者微信号
        String FromUserName = XMLUtil.readNode(root, "FromUserName");
        String CreateTime = XMLUtil.readNode(root, "CreateTime");
        String Event = XMLUtil.readNode(root, "Event");
        System.out.println("MsgType="+MsgType+"\n---ToUserName="+ToUserName+"\n---FromUserName="
        +FromUserName+"\n---CreateTime="+CreateTime+"\n---Event="+Event);
        if (MsgType.equals(Constant.REQ_MESSAGE_TYPE_EVENT)) {
            /**
             * 用户关注了微信号啦
             */
            if(Event.equals(Constant.EVENT_TYPE_SUBSCRIBE)){
                /**
                 * 获取用户信息保存到数据库
                 */
                System.out.println("用户关注了微信号啦");
                Map map = WxUserinfoByOpenId(FromUserName);
                System.out.println(map.toString());
                System.out.println("unionid=="+map.get("unionid"));
            }
            /**
             * 用户取消关注啦
             */
            else if(Event.equals(Constant.EVENT_TYPE_UNSUBSCRIBE)){
                System.out.println("用户取消关注啦");
                Map map = WxUserinfoByOpenId(FromUserName);
                System.out.println(map.toString());
                System.out.println("unionid=="+map.get("unionid"));

            }
                out.close();
        }
    }

    /**
     * 根據openId獲取微信端的用戶信息
     * @param openId
     * @return
     * @throws IOException
     */
    public static Map WxUserinfoByOpenId(String openId) throws IOException {
        System.out.println("===========WxUserinfoByOpenId");
        HttpUtil httpUtil = new HttpUtil();
        String url = "https://api.weixin.qq.com/cgi-bin/user/info";
        String accessToken = (String)getAccessToken().get("access_token");
        String result = httpUtil.header("X-Requested-With", "XMLHttpRequest")
                .data("openid", openId)
                .data("access_token",accessToken)
                .data("lang", "zh_CN")
                .url(url)
                .get();
        System.out.println("WxUserinfoByOpenId==="+result);
        Map map = JSONObject.parseObject(result, Map.class);
        return map;
    }

    /**
     * 獲取公眾號的access_token
     * @return
     * @throws IOException
     */
    public static Map getAccessToken() throws IOException {
        System.out.println("===========getAccessToken");
        HttpUtil httpUtil = new HttpUtil();
        String url = "https://api.weixin.qq.com/cgi-bin/token";
        String result = httpUtil.header("X-Requested-With", "XMLHttpRequest")
                .data("appid", Mark.GZH_APPID)
                .data("secret", Mark.GZH_APPSECRET)
                .data("grant_type", Mark.TOKEN_GRANT_TYPE)
                .url(url)
                .get();
        System.out.println(result);
        Map map = JSONObject.parseObject(result, Map.class);
        if (!map.containsKey("access_token")) {
            throw new ServiceException("错误信息:" + map.get("errmsg"));
        }
        return map;
    }
}

3.SendWxMessage

package com.youruan.logistics.util;

import com.alibaba.fastjson.JSONObject;
import com.youruan.logistics.entity.WxTemplate;


/**
 * 发送消息模板的类
 */
public class SendWxMessage {
    public static boolean sendTemplateMsg(String token, WxTemplate template){

        boolean flag=false;

        String requestUrl="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
        requestUrl=requestUrl.replace("ACCESS_TOKEN", token);

        String jsonResultT=CommonUtil.httpRequest(requestUrl, "POST", template.toJSON());
        JSONObject jsonResult = JSONObject.parseObject(jsonResultT);
        if(jsonResult!=null){
            int errorCode=jsonResult.getInteger("errcode");
            String errorMessage=jsonResult.getString("errmsg");
            if(errorCode==0){
                flag=true;
            }else{
                System.out.println("模板消息发送失败:"+errorCode+","+errorMessage);
                flag=false;
            }
        }
        return flag;



    }
}

4.SignUtil(公众号校验)

package com.youruan.logistics.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

public class SignUtil {

    private static String token = "tongfenfen";
    /**
     * 校验签名
     */
    public static boolean checkSignature(String signature, String timestamp, String nonce) {
        System.out.println("signature:" + signature + "timestamp:" + timestamp + "nonc:" + 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对比,标识该请求来源于微信
        System.out.println(tmpStr.equals(signature.toUpperCase()));
        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;
    }
}

5.XMLUtil(解析xml数据)

package com.youruan.logistics.util;


import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

public class XMLUtil {
    public static String content="";
    public static Document  readString2XML(String str){
        Document document=null;
        try {
            document=DocumentHelper.parseText(str);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return document;
    };
    /**
     * 读取根节点下每一个节点信息
     * @param node
     * @return
     */
    public static String readNodes(Element node){
        content+=node.getName()+":"+node.getTextTrim()+"\n";
        //递归遍历当前节点所有的子节点
        List listElement=node.elements();//所有一级子节点的list
        for(Element e:listElement){//遍历所有一级子节点
            readNodes(e);//递归
        }
        return content;
    }
    /**
     * 读取单个节点信息
     * @param node
     * @param name
     * @return
     */
    public static String readNode(Element node,String name){
        Element e=node.element(name);
        String nodeString=e.getTextTrim();
        return nodeString;

    }
}

6.HttpUtilOfWx

package com.youruan.logistics.util;


import com.alibaba.fastjson.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;


public class HttpUtilOfWx {
    public static String httpUrlConnect(String httpUrl, String params,
                                        String method) throws Exception {

        URL url = new URL(httpUrl);
        HttpURLConnection urlConnection = (HttpURLConnection) url
                .openConnection();
        urlConnection.setRequestProperty("accept", "*/*");
        urlConnection.setRequestProperty("connection", "Keep-Alive");
        urlConnection.setRequestProperty("user-agent",
                "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        urlConnection.setDoOutput(true);
        urlConnection.setDoInput(true);
        urlConnection.setRequestMethod(method);
        urlConnection.connect();
        PrintWriter out = null;
        BufferedReader in = null;
        if (null != params && !"".equals(params)) {
            out = new PrintWriter(new OutputStreamWriter(
                    urlConnection.getOutputStream(), "utf-8"));
            out.print(params);
            out.flush();
        }
        in = new BufferedReader(new InputStreamReader(
                urlConnection.getInputStream(), "utf-8"));
        String line;
        String result = "";
        while ((line = in.readLine()) != null) {
            result += line;
        }
        return result;

    }
    /**
     * 根据字符串json数据解析access_token
     * @param jsonStr
     * @return map
     */
    public static Map getAccessTokenByJsonStr(String jsonStr){
       /* JSONObject jsonObj = new JSONObject(jsonStr);
        if(jsonObj.has("access_token")){
            map.put("access_token", jsonObj.get("access_token"));
        }
        if(jsonObj.has("expires_in")){
            map.put("expires_in", jsonObj.get("expires_in"));
        }*/
        Map map = JSONObject.parseObject(jsonStr, Map.class);
        /*if (!map.containsKey("openid")) {
            throw new ServiceException("错误信息:" + map.get("errmsg"));
        }*/
        return map;
    }

}

7.实体类TemplateParam

package com.youruan.logistics.entity;

public class TemplateParam {
    //模板消息由于模板选取不同,那么就要封装俩个实体类
    // 参数名称
    private String name;
    // 参数值
    private String value;
    // 颜色
    private String color;

    public TemplateParam() {
        super();
        // TODO Auto-generated constructor stub
    }
    public TemplateParam(String name,String value,String color){
        this.name=name;
        this.value=value;
        this.color=color;
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

8.实体类 WxTemplate

package com.youruan.logistics.entity;

import java.util.List;
/**
 * 模板基类
 *
 */
public class WxTemplate {
    //消息接收方
    private String toUser;
    //模板id
    private String templateId;
    //模板消息详情链接
    private String url;
    //消息顶部的颜色
    private String topColor;
    //参数列表
    private List templateParamList;

    public WxTemplate() {
        super();
        // TODO Auto-generated constructor stub
    }
    public WxTemplate(String toUser, String templateId, String url,
                    String topColor, List templateParamList) {
        super();
        this.toUser = toUser;
        this.templateId = templateId;
        this.url = url;
        this.topColor = topColor;
        this.templateParamList = templateParamList;
    }
    public String getToUser() {
        return toUser;
    }
    public void setToUser(String toUser) {
        this.toUser = toUser;
    }
    public String getTemplateId() {
        return templateId;
    }
    public void setTemplateId(String templateId) {
        this.templateId = templateId;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getTopColor() {
        return topColor;
    }
    public void setTopColor(String topColor) {
        this.topColor = topColor;
    }
    public List getTemplateParamList() {
        return templateParamList;
    }
    public void setTemplateParamList(List templateParamList) {
        this.templateParamList = templateParamList;
    }

    public String toJSON() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("{");
        buffer.append(String.format("\"touser\":\"%s\"", this.toUser)).append(",");
        buffer.append(String.format("\"template_id\":\"%s\"", this.templateId)).append(",");
        buffer.append(String.format("\"url\":\"%s\"", this.url)).append(",");
        buffer.append(String.format("\"topcolor\":\"%s\"", this.topColor)).append(",");
        buffer.append("\"data\":{");
        TemplateParam param = null;
        for (int i = 0; i < this.templateParamList.size(); i++) {
            param = templateParamList.get(i);
            // 判断是否追加逗号
            if (i < this.templateParamList.size() - 1){

                buffer.append(String.format("\"%s\": {\"value\":\"%s\",\"color\":\"%s\"},", param.getName(), param.getValue(), param.getColor()));
            }else{
                buffer.append(String.format("\"%s\": {\"value\":\"%s\",\"color\":\"%s\"}", param.getName(), param.getValue(), param.getColor()));
            }

        }
        buffer.append("}");
        buffer.append("}");
        return buffer.toString();
    }
}

9.Constant

	/**
     * 微信触发的事件
     */
    public static final Object REQ_MESSAGE_TYPE_EVENT = "event";

    public static final Object EVENT_TYPE_SUBSCRIBE = "subscribe";          //关注

    public static final Object EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";  //取消关注

你可能感兴趣的:(java)