java 对接微信公众号(二)获取关注取关事件/用户回复消息

1、公众号后台配置:点击基本配置-修改配置

URL:填写服务端建立的接口地址(接口要能接受get/post请求)

token:随便写

秘钥:自动生成

 

配好之后,点击提交,微信会往接口发送一条get请求的数据,服务端校验后,把微信发送的数据中的echoStr字段原样返回,微信接收到会提示修改成功。

2、配置服务端接口



    /**
     * 接受微信发送的消息
     *  @param request 公参
     *  @return 返回结果
     */
    @SneakyThrows
    @RequestMapping(value = "/getTencentMsg", method = {RequestMethod.POST, RequestMethod.GET})
    @ApiIgnore
    public void getTencentMsg(HttpServletRequest request, HttpServletResponse response) {
        String method = request.getMethod();
        if(RequestMethodEnum.GET.getDesc().equals(method)){
            String signature = request.getParameter("signature");
            String timestamp = request.getParameter("timestamp");
            String nonce = request.getParameter("nonce");
            String echoStr = request.getParameter("echostr");
            String token = "weiyouzz";
            boolean checkSignature = wxUtils.checkSignature(signature, timestamp, nonce, token);
            if (checkSignature) {
                response.getWriter().write(echoStr+"");
            }
        }else {
            //post请求跟消息相关,往下翻到第三点
        }
    }



//校验微信请求


    /**
     * 验证微信签名
     */
    public boolean checkSignature(String signature, String timestamp,String nonce, String token) {
        // 1.将token、timestamp、nonce三个参数进行字典序排序
        String[] arr = new String[]{token, timestamp, nonce};
        Arrays.sort(arr);
        // 2. 将三个参数字符串拼接成一个字符串进行sha1加密
        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;
        // 3.将sha1加密后的字符串可与signature对比,标识该请求来源于微信
        return tmpStr != null && tmpStr.equals(signature.toUpperCase());
    }

    private static String byteToStr(byte[] byteArray) {
        StringBuilder strDigest = new StringBuilder();
        for (int i = 0; i < byteArray.length; i++) {
            strDigest.append(byteToHexStr(byteArray[i]));
        }
        return strDigest.toString();
    }

    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;
    }
//可能用到的包
import java.util.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import lombok.SneakyThrows;
import springfox.documentation.annotations.ApiIgnore;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

RequestMethodEnum枚举自己建或者复制下面的

public enum RequestMethodEnum {

    /** get*/
    GET(1,"GET"),
    /** post*/
    POST(2,"POST");

    private final Integer code;
    private final String desc;

    RequestMethodEnum(Integer id, String name){
        this.code = id;
        this.desc = name;
    }

    public Integer getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }
}

3、获取消息并回应,还是走上面这个接口,但是请求方式是post

        else {
            // 预先设定返回的 response 类型为 xml
            tencentAdvertisingService.getMessage(request,response);
        }
    @Override
    public void getMessage(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Content-type", "application/xml");
            // 读取参数,解析Xml为map
            Map<String, String> map = wxUtils.transferXmlToMap(wxUtils.readRequest(request));
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(map));
            if(ObjectUtils.isNotEmpty(jsonObject)){
                String msgType = jsonObject.getString("MsgType");
                String toUserName = jsonObject.getString("ToUserName");
                String fromUserName = jsonObject.getString("FromUserName");
                String createTime = jsonObject.getString("CreateTime");
                

                //回复,可以回复表情,蓝色可点击链接文字等
                String content ;
                if (TencentMsgTypeConstant.EVENT.equals(msgType)) {//关注自动回复
                    content = "[Party]终于等到你!欢迎你的关注!\n" +
                            "<a href=\"https://www.baidu.com\">百度</a>\n" +
                            "\n" +
                            "<a href=\"https://www.csdn.net\">CSDN</a>\n" +
                            "\n" +
                            "/:rose点击<a href=\"https://www.csdn.net\">【CSDN】</a>看更多优质博客\n" +
                            "/:gift点击<a href=\"https://www.csdn.net\">【CSDN】</a>看更多优质博客";
                } else {//收到消息自动回复
                    content = "/:sun已经收到您的消息~\n" +
                            ">> <a href=\"https://www.csdn.net\">【CSDN】</a>\n" +
                            ">> <a href=\"https://www.csdn.net\">【CSDN】</a>\n" +
                            ">> <a href=\"https://www.csdn.net\">【CSDN】</a>\n" +
                            ">> <a href=\"https://www.csdn.net\">【CSDN】</a>\n" +
                            ">> <a href=\"https://www.csdn.net\">【CSDN】</a>";
                }
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write(getXmlReturnMsg(fromUserName,toUserName,System.currentTimeMillis() / 1000,content));
            }
        }catch (Exception e){log.info(e.getMessage());}
    }






    //工具类
    public Map transferXmlToMap(String strxml) throws IOException {
        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
        if (null == strxml || "".equals(strxml)) {
            return null;
        }
        Map m = new HashMap();
        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
        SAXBuilder builder = new SAXBuilder();
        Document doc = null;
        try {
            doc = builder.build(in);
        } catch (JDOMException e) {
            // 统一转化为 IO 异常输出
            throw new IOException(e.getMessage());
        }
        // 解析 DOM
        Element root = doc.getRootElement();
        List list = root.getChildren();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Element e = (Element) it.next();
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if (children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = getChildrenText(children);
            }
            m.put(k, v);
        }
        //关闭流
        in.close();
        return m;
    }

    /**
     * 辅助 transferXmlToMap 方法递归提取子节点数据
     */
    private String getChildrenText(List<Element> children) {
        StringBuffer sb = new StringBuffer();
        if (!children.isEmpty()) {
            Iterator<Element> it = children.iterator();
            while (it.hasNext()) {
                Element e = (Element) it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List<Element> list = e.getChildren();
                sb.append("<" + name + ">");
                if (!list.isEmpty()) {
                    sb.append(getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }
        return sb.toString();
    }

    /**
     * 读取 request body 内容作为字符串
     *
     * @param request
     * @return
     * @throws IOException
     */
    public String readRequest(HttpServletRequest request) throws IOException {
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String str;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((str = in.readLine()) != null) {
            sb.append(str);
        }
        in.close();
        inputStream.close();
        return sb.toString();
    }
    /**
     * 构建普通消息
     * @param toUser 接收方账号(openId)
     * @param fromUser 开发者账号
     * @param createTime 创建时间,整型
     * @param content 内容
     * @return 回复消息
     */
    public String getXmlReturnMsg(String toUser,String fromUser,Long createTime,String content) {
        return "<xml>\n" +
                "  <ToUserName><![CDATA["+toUser+"]]></ToUserName>\n" +
                "  <FromUserName><![CDATA["+fromUser+"]]></FromUserName>\n" +
                "  <CreateTime>"+createTime+"</CreateTime>\n" +
                "  <MsgType><![CDATA[text]]></MsgType>\n" +
                "  <Content><![CDATA["+content+"]]></Content>\n" +
                "</xml>";
    }

猜你喜欢

转载自blog.csdn.net/qq_37928038/article/details/123416947