微信服务(公众)号实现用户关注自动注册成为会员

举报
穆雄雄 发表于 2022/12/06 20:09:43 2022/12/06
【摘要】 大家好,我是雄雄。交流技术可以进入到我的社区【雄雄的小课堂】 前言看本篇文章之前,可以先看看前面两篇:java实现微信服务(公众)号用户关注时,获取openid,安全模式下的加密解密实现微信公众平台安全模式下传输xml数据包时解密方式前面这两篇文章主要实现的,当用户关注了服务号或者订阅号之后,通过触发事件,然后会给开发者配置的接口中,传输加密的xml格式数据,后台通过解密xml格式数据,拿到...

大家好,我是雄雄。交流技术可以进入到我的社区【雄雄的小课堂】

在这里插入图片描述

前言

看本篇文章之前,可以先看看前面两篇:
java实现微信服务(公众)号用户关注时,获取openid,安全模式下的加密解密实现

微信公众平台安全模式下传输xml数据包时解密方式

前面这两篇文章主要实现的,当用户关注了服务号或者订阅号之后,通过触发事件,然后会给开发者配置的接口中,传输加密的xml格式数据,后台通过解密xml格式数据,拿到自己想要的东西。

解密xml数据,提取内容

在前两篇文章中也提到过,我们开启服务器配置时,需要在后台写两个同名接口,只是一个是get方式请求,另一个是post方式请求,具体的在这不在赘述。

现在我们来看看代码的实现。


    /**
     * 接收用户事件
     * @param requestBody
     * @return
     */
    @RequestMapping(value = "/validationWeCat",method = RequestMethod.POST)
    public String validationWeCat(@RequestBody String requestBody){
        if(Strings.isNotBlank(requestBody)){
            log.info("进入了validationWeCat的post方法,由用户触发的,值是:"+requestBody);
            //解析xml数据
            JSONObject jsonObject = WeChatUtils.toParseTheXmlData(requestBody);
            int code = jsonObject.getInteger("code");
            if(code==200){
                //获取关注的密文
                String miwen = jsonObject.getString("encrypt");
                //解密
                String jiemiText = WeChatUtils.decodeNewUsers(miwen);
                //解密完之后还是个xml数据,继续解析
                JSONObject jiemiObject = WeChatUtils.toParseTheXmlData(jiemiText);
                if(jiemiObject.getInteger("code")==200){
                    //获取消息类型
                    String msgType =  jiemiObject.getString("msgType");
                    switch (msgType){
                        //文本
                        case "text" :
                            break;
                        //事件
                        case "event" :
                            //触发事件执行的方法
                            eventCase(jiemiObject);
                            break;
                        // 语音
                        case "voice" :
                            break;
                        // 视频
                        case "video" :
                            break;
                        // 音乐
                        case "music" :
                            break;
                        // 图文
                        case "news" :
                            break;
                        // 图片
                        case "image" :
                            break;
                        // 小视频
                        case "shortvideo" :
                            break;
                        // 地理位置
                        case "location" :
                            break;
                        // 链接
                        case "link" :
                            break;
                        default:
                            break;
                    }

                }else{
                    log.error("解析xml报错");
                }
            }else{
                log.error("解析xml报错");
            }
        }
        return requestBody;
    }

    /**
     * 触发的是事件
     * @param jsonObject
     */
    public void eventCase(JSONObject jsonObject){
        //获取事件类型
        String event =  jsonObject.getString("event");
        switch (event){
            //关注
            case "subscribe" :
                //获取微信号
                String weChatNum = jsonObject.getString("toUserName");
                //获取openid
                String openid = jsonObject.getString("fromUserName");
                Member member = new Member();
                member.setWechat(weChatNum);
                member.setOpenIdGzh(openid);
                //默认名字是:微信用户
                member.setName("公众号用户");
                boolean flag = saveMember(member);
                if(!flag){
                    log.error("添加会员报错");
                }
                break;
            //取消关注
            case "unsubscribe" :
                break;
            // 用户已关注时的事件推送
            case "SCAN" :
                break;
            // 用户已关注时的事件推送
            case "LOCATION" :
                break;
            // 点击菜单拉取消息时的事件推送
            case "CLICK" :
                break;
            // 点击菜单跳转链接时的事件推送
            case "VIEW" :
                break;
            default:
                break;
        }
    }
/**
     * 添加会员的业务逻辑
     */
    public boolean saveMember(LtMember ltMember){
       
            return memberService.save(ltMember);
        
        return false;
    }

上面就是添加会员的基本操作,涉及到了一个工具类,我这边也放出来吧,此工具类主要是用来解析xml数据的,代码如下:

package org.jeecg.modules.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.config.WeChatContant;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 * @author: muxiongxiong
 * @date: 2022年08月17日 下午 10:06
 * 公众号:雄雄的小课堂
 * 博客:https://blog.csdn.net/qq_34137397
 * 个人站:http://www.穆雄雄.com
 * 个人站:http://www.muxiongxiong.cn
 * @Description: 微信工具类,主要是用来加密和解密信息
 */
@Slf4j
public class WeChatUtils {
	    /**
     * 解析xml数据的工具类
     * @param xmlTest
     * @return
     */
    public static JSONObject toParseTheXmlData(String xmlTest){
        //new LinkedHashMap<>() 表示让集合添加的时候有顺序
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            //这里也不知道是啥意思
            dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
            dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
            dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
            dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            dbf.setXIncludeAware(false);
            dbf.setExpandEntityReferences(false);
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(xmlTest);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);
            //得到根节点
            Element root = document.getDocumentElement();
            //用户关注触发事件之后微信传过来加密的信息
            NodeList encryptNode = root.getElementsByTagName("Encrypt");
            //开发者微信号
            NodeList toUserNameNode = root.getElementsByTagName("ToUserName");
            //发送方帐号(一个OpenID)
            NodeList fromUserNameNode = root.getElementsByTagName("FromUserName");
            //消息类型,event
            NodeList msgTypeNode = root.getElementsByTagName("MsgType");
            //事件类型,subscribe(订阅)、unsubscribe(取消订阅)
            NodeList eventNode = root.getElementsByTagName("Event");
            //消息创建时间 (整型)
            NodeList createTimeNode = root.getElementsByTagName("CreateTime");
            //事件 KEY 值,qrscene_为前缀,后面为二维码的参数值
            NodeList eventKeyNode = root.getElementsByTagName("EventKey");
            //二维码的ticket,可用来换取二维码图片
            NodeList ticketNode = root.getElementsByTagName("Ticket");
            //地理位置纬度
            NodeList latitudeNode = root.getElementsByTagName("Latitude");
            //地理位置经度
            NodeList longitudeNode = root.getElementsByTagName("Longitude");
            //地理位置精度
            NodeList precisionNode = root.getElementsByTagName("Precision");

            //获取该节点下的值,将值添加到jsonobject中
            if(encryptNode.getLength()>0){
                String encrypt = encryptNode.item(0).getTextContent();
                jsonObject.put("encrypt",encrypt);
            }
            if (toUserNameNode.getLength()>0) {
                String toUserName = toUserNameNode.item(0).getTextContent();
                jsonObject.put("toUserName",toUserName);
            }
            if (fromUserNameNode.getLength()>0) {
                String fromUserName = fromUserNameNode.item(0).getTextContent();
                jsonObject.put("fromUserName",fromUserName);
            }
            if (msgTypeNode.getLength()>0) {
                String msgType = msgTypeNode.item(0).getTextContent();
                jsonObject.put("msgType",msgType);
            }
            if (eventNode.getLength()>0) {
                String event = eventNode.item(0).getTextContent();
                jsonObject.put("event",event);
            }
            if (createTimeNode.getLength()>0) {
                String createTime = createTimeNode.item(0).getTextContent();
                jsonObject.put("createTime",createTime);
            }
            if (eventKeyNode.getLength()>0) {
                String eventKey = eventKeyNode.item(0).getTextContent();
                jsonObject.put("eventKey",eventKey);
            }
            if (ticketNode.getLength()>0) {
                String ticket = ticketNode.item(0).getTextContent();
                jsonObject.put("ticket",ticket);
            }
            if (latitudeNode.getLength()>0) {
                String latitude = latitudeNode.item(0).getTextContent();
                jsonObject.put("latitude",latitude);
            }
            if (longitudeNode.getLength()>0) {
                String longitude = longitudeNode.item(0).getTextContent();
                jsonObject.put("longitude",longitude);
            }
            if (precisionNode.getLength()>0) {
                String precision = precisionNode.item(0).getTextContent();
                jsonObject.put("precision",precision);
            }
            jsonObject.put("code",200);
            jsonObject.put("msg","操作成功");


        }catch (Exception exception){
            jsonObject.put("code",500);
            jsonObject.put("msg","出异常了");
            jsonObject.put("error",exception.getMessage());
        }

        return jsonObject;

    }
}

}

至此,就可以实现关注后自动将会员注册到我们实际库中。后面的业务根据这个架构往下写就行,就比较简单了。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。