微信推广带id二维码生成详细解读

欢迎加入ifast 交流群,

群聊号码:746358408 ,

关注的朋友请加群,博客留言信息不带回哈

 

需求:登录用户产生一个二维码,下一个人扫描这个二维码之后关注公众号,登录之后自动成为第一个用户的粉丝

吐槽一把,这个需求很操蛋。。。。但是,操不操蛋那是你程序猿说的不?微信开发本来就相当操蛋了。。。都懂得,文档又少,限制又多,傻逼的很。。。。 

首先看下微信官方的文档,我们先了解下需要哪些东西

当然毫不犹豫的点开。。。 然后发现这个。。 

却发现,并没有神马卵用 。。。。。。。。  生成二维码需要token ,我们就按照他提供的方法来搞一搞了。。。 就按照他提供的方法搞一搞了。。 

二维码的几种生成方式,在这里就不解释了。。 

不够简单粗暴,我直接上java代码了。。。。。 


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
 
import net.sf.json.JSONObject;
 
public class Test {
 
    static String wechatAppID = "";
    static String wechatAppSecret = "";
    static String wechatAccessTokenUrl = "";
 
    public static String getWechatAccessToken() {
 
        try {
            URL object = new URL(wechatAccessTokenUrl + "&appid=" + wechatAppID + "&secret=" + wechatAppSecret);
            HttpURLConnection con = (HttpURLConnection) object.openConnection();
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setRequestProperty("Content-Type", "application/json");
            con.setRequestProperty("Accept", "application/json");
            con.setRequestMethod("GET");
 
            OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream(), "utf-8");
            wr.flush();
            // 显示 POST 请求返回的内容
            StringBuilder sb = new StringBuilder();
            int HttpResult = con.getResponseCode();
            if (HttpResult == HttpURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
                String line = null;
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                }
                br.close();
                System.out.println("" + sb.toString());
            } else {
                System.out.println(con.getResponseMessage());
            }
 
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        return "";
    }
 
    public static String getUserQRCode(Integer userId) {
        JSONObject jsonObject = JSONObject.fromObject(getWechatAccessToken());
        String access_token = jsonObject.getString("access_token");
        try {
            URL object = new URL("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + access_token);
            HttpURLConnection con = (HttpURLConnection) object.openConnection();
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setRequestProperty("Content-Type", "application/json");
            con.setRequestProperty("Accept", "application/json");
            con.setRequestMethod("POST");
            JSONObject data = new JSONObject();
            data.put("action_name", "QR_LIMIT_SCENE");
            JSONObject dojb = new JSONObject();
            dojb.put("scene_id", userId);
            JSONObject cojb = new JSONObject();
            cojb.put("scene", dojb);
            data.put("action_info", cojb);
            OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream(), "utf-8");
            wr.write(data.toString());
            wr.flush();
            // 显示 POST 请求返回的内容
            StringBuilder sb = new StringBuilder();
            int HttpResult = con.getResponseCode();
            if (HttpResult == HttpURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
                String line = null;
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                }
                br.close();
 
                JSONObject jsonObj = JSONObject.fromObject(sb.toString());
                String ticket = jsonObj.getString("ticket");
                 生成二维码
                return "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket;
 
            } else {
                System.out.println(con.getResponseMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        return "";
    }
 
}


运行这两段代码之后,我们发现我们的二维码居然生成了 ,第二个方法返回一个字符串就是二维码图片的绝对路径。。。。 生成的二维码我在这里就不解释了 。。 截出来也没有神马卵用。。。  我们回头看看方法。。。

我们发现我们用的是scene_id ,而没有使用字符串,为啥子????????  这个问题很关键二维码是生成了,但是怎么把二维码里面的id和下一个用户关联起来了?下一个用户关注上一个用户的二维码,我擦,我怎么知道啥时候关注了了 ???? 如果把上下级用户关联起来了 ?  重重问题 。。。 各种蛋疼。。。 

首先,当用户点击微信公众号关注的时候,后台是如何知道哪个用户点击了关注了 ? 那么就有这么一个问题,那就是通信的问题,当用户点击关注,微信公众号如何跟我们自己的后台通信了 ???? 这个很关键

你需要在微信公众号的后台做一些配置,打开后台

IP白名单,就是哪些IP有权限调用这些接口,一般配置你服务器的IP和你开发电脑的公网IP(不是192.168.0.111),好吧,来张图吧。。 

然后启动这东西 。。。 

然后填写以下配置。。。 

URL:其实就是一个外网可以访问的接口,注意:必须是80或443端口,做过后台都懂得。。。 这个接口的作用是,被微信调用,然后产生回调。。。。。也就是微信通过这个接口你的服务器发送消息。这个很重要

Token:自己定义的一个字符串,加密的要是,你写jinsanpang都可以;可以参考我的另外一篇文章了解token(http://blog.csdn.net/chmod_r_755/article/details/75554735)

EncodeKey:随机生成,干啥子用的,不知道,问微信

模式:明文模式,你想怎样? 加密? 搞得跟真的似的 ,有意思吗?金融机构自己看着办 。。。。 

到这里,我们就明白了,用户关注微信我们的后台是怎么知道的。。。原来是有通信的 。。。这块我们就必须搞一个接口了,让微信回调。。。。。。 

说太抽象了 。。。。  我们首先来张图 。。 

当我扫码关注的时候, 微信会回调这个接口,注意我这边日志是json格式的,但是网上有xml版本的

这种格式的,因为我把xml转json了,xml看着都蛋疼 ,来段代码压压惊


@RequestMapping(value = "/wx.do")
    public void get(@RequestBody(required = false) String body, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
 
        org.json.JSONObject jsonObject = JSONML.toJSONObject(body);
        logger.info("请求进来了..." + jsonObject);
 
        org.json.JSONArray jsonArray = jsonObject.getJSONArray("childNodes");
 
        org.json.JSONObject fromUser = null;
        org.json.JSONObject event = null;
        org.json.JSONObject eventKey = null;
 
        for (int i = 0; i < jsonArray.length(); i++) {
            org.json.JSONObject obj = jsonArray.getJSONObject(i);
 
            String tagName = obj.getString("tagName");
 
            if ("FromUserName".equals(tagName)) {
                fromUser = obj;
            } else if ("Event".equals(tagName)) {
                event = obj;
            } else if ("EventKey".equals(tagName)) {
                eventKey = obj;
            }
        }
 
        logger.info("请求进来了...fromUser=" + fromUser.toString() + "    event=" + event.toString() + "    eventKey="
                + eventKey.toString());
 
        if (event != null && eventKey != null && fromUser != null) {
 
            org.json.JSONArray eventArray = event.getJSONArray("childNodes");
            org.json.JSONArray eventKeyArray = eventKey.getJSONArray("childNodes");
            org.json.JSONArray fromUserNameArray = fromUser.getJSONArray("childNodes");
 
            logger.info("请求进来了...eventArray=" + eventArray.toString() + "    eventKeyArray=" + eventKeyArray.toString()
                    + "    fromUserNameArray=" + fromUserNameArray.toString());
            if (eventArray.length() > 0 && fromUserNameArray.length() > 0 && eventKeyArray.length() > 0) {
                String subscribeString = eventArray.getString(0); // 动作
                String fromUserString = fromUserNameArray.getString(0); // openId
                String eventKeyString = eventKeyArray.getString(0); // 带入的信息
 
                logger.info("请求进来了...subscribeString=" + subscribeString + "    fromUserString=" + fromUserString
                        + "    eventKeyString=" + eventKeyString);
 
                if ("subscribe".equals(subscribeString)) {
                    // 点击关注, 保存上级的id 且保存openId
                    // 点击取消关注,删除这条记录
                    // 如果 eventKeyString 为空字符串 ,表示关注官方二维码关注的
                    /// 包含上级Id ,则保存到数据库中
                    if (eventKeyString.contains("qrscene_")) {
                        String userIdString = eventKeyString.replaceAll("qrscene_", "");
                        Integer userId = Integer.parseInt(userIdString);
                        WechatKey wechatKey = new WechatKey();
                        wechatKey.setOpenId(fromUserString);
                        wechatKey.setUserId(userId);
                        wechatKeyManager.saveWechatkey(wechatKey);
 
                    }
 
                } else if ("unsubscribe".equals(subscribeString)) {
                    WechatKey wechatKey = wechatKeyManager.getWechatKeyByOpenId(fromUserString);
                    if (wechatKey != null) {
                        wechatKeyManager.deleteByOpenId(fromUserString);
                    }
                }
 
            }
 
        }
 
        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.error(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 (CheckUtil.checkSignature(signature, timestamp, nonce)) {
            out.print(echostr);
        }
        out.close();
        out = null;
 
    }


关注的时候微信会给服务器推送一条消息

subscribe:表示开始关注

fromUser:表示哪个用户关注的,这里返回的是当前用户的openId ,唯一的 

EventKey:qrscene_20 前面的qrscene_是固定的,后面的20 也就是上个用户的id

那么到了这一步, 上个用户和下一个用户就联系在一起了。。。。。。如果扫的码是系统生成的。。。EventKey:就为空字符串了。。

扯到这里了 。。。。  其他的不解释,自己理解。。。。 


--------------------- 
作者:chmod_R_755 
来源:CSDN 
原文:https://blog.csdn.net/chmod_R_755/article/details/76229056 
版权声明:本文为博主原创文章,转载请附上博文链接!

来源:https://blog.csdn.net/chmod_R_755/article/details/76229056

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值