
微信公众号生成带参数二维码跳转关注与未关注以及事件推送
生成二维码的动作主要有两步,第一步根据参数拿到二维码ticket,第二步根据ticket换取二维码
拼接结构如下:{“action_name”: “QR_LIMIT_SCENE”, “action_info”: {“scene”: {“scene_id”: 123}}} 注意scene是在action_info 里面的 请求URL为 :https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN 类型为POST 返回数据是这样的 {“ticket”:“gQH47joAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL2taZ2Z3TVRtNzJXV1Brb3ZhYmJJAAIEZ23sUwMEmm 3sUw==”,“expire_seconds”:60,“url”:“http://weixin.qq.com/q/kZgfwMTm72WWPkovabbI”} 下面上具体代码
事件推送的URL需要在公众号后台自行配置,是一个URL哦~不同的事件按照分类进行区别开发 二维码的推送参数如下:
这是我代码中打印的 已关注用户推送的
根据这个我们能拿到二维码携带过来的参数 就是Eventkey。 未关注用户推送的:
注意未关注用户的参数前面带一个qrscene_ 获取时自行截取
消息类型是这样,我的需求是要跳转到小程序 并没有链接类型 所以就使用文本类型,里面自己嵌入链接,官方给出了方法
发布日期:2021-05-06 19:33:02
浏览次数:17
分类:技术文章
本文共 6781 字,大约阅读时间需要 22 分钟。
首先说下业务场景
需要从某个页面生成二维码,用户扫描二维码,如果已关注公众号,跳到公众号页面,推送小程序链接 如果还未关注公众号,跳转到关注页面,关注公众号后推送小程序链接。 当然从公众号跳转到小程序,多多少少是需要带一点业务相关参数的。 本篇主要将二维码生成,以及事件推送一、二维码生成
根据官方文档介绍,目前公众号二维码主要有永久和临时两种,但是永久二维码是有数量限制的,临时二维码携带参数又有限制。
所以我们一般都使用临时二维码
首先看获取二维码的参数

/** * 创建临时带参二维码 * * @param accessToken 接口访问凭证 * @param expireSeconds 二维码有效时间,单位为秒,最大不超过1800 * @param sceneId 场景ID * @return WeixinQRCode */ public WeixinQRCode createTemporaryQRCode(String accessToken, int expireSeconds, String sceneStr) { QRCodeParMapping byMappingValue = qrCodeParamMappingUtil.getQrcodeParMappingByMappingValue(sceneStr); Integer mappingID = null; if (byMappingValue == null) { byMappingValue = new QRCodeParMapping(); byMappingValue.setMappingValue(sceneStr); qrCodeParamMappingUtil.save(byMappingValue); } mappingID = byMappingValue.getMappingID(); sceneStr = mappingID.toString(); System.out.println("二维码携带参数为" + sceneStr); WeixinQRCode weixinQRCode = null; // 拼接请求地址 String requestUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN"; requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken); // 需要提交的json数据 String jsonMsg = "{\"expire_seconds\": %d, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": %s}}}"; // 创建临时带参二维码 JSONObject jsonObject = WechatUtil.httpsRequest(requestUrl, "POST", String.format(jsonMsg, expireSeconds, sceneStr)); if (null != jsonObject) { try { weixinQRCode = new WeixinQRCode(); weixinQRCode.setTicket(jsonObject.getString("ticket")); weixinQRCode.setExpireSeconds(jsonObject.getInt("expire_seconds")); logger.info("创建临时带参二维码成功 ticket:{} expire_seconds:{}", weixinQRCode.getTicket(), weixinQRCode.getExpireSeconds()); } catch (Exception e) { weixinQRCode = null; int errorCode = jsonObject.getInt("errcode"); String errorMsg = jsonObject.getString("errmsg"); logger.error("创建临时带参二维码失败 errcode:{} errmsg:{}", errorCode, errorMsg); } } return weixinQRCode; } /** * 发起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; StringBuffer buffer = new StringBuffer(); 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 httpUrlConn = (HttpsURLConnection) url.openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 设置请求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect(); // 当有数据需要提交时 if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意编码格式,防止中文乱码 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 将返回的输入流转换成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 释放资源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); jsonObject = JSONObject.fromObject(buffer.toString()); } catch (ConnectException ce) { log.error("Weixin server connection timed out."); } catch (Exception e) { log.error("https request error:{}", e); } return jsonObject; }/** * 临时二维码信息 * * @author liufeng * @date 2013-11-10 */public class WeixinQRCode { // 获取的二维码ticket private String ticket; // 二维码的有效时间,单位为秒,最大不超过1800 private int expireSeconds; public String getTicket() { return ticket; } public void setTicket(String ticket) { this.ticket = ticket; } public int getExpireSeconds() { return expireSeconds; } public void setExpireSeconds(int expireSeconds) { this.expireSeconds = expireSeconds; }}一共两个方法 一个类第一个方法是生成二维码的步骤,三个参数:1、accessToken 请自备2、过期时间 3、二维码携带参数第二个方法是访问微信的GET请求第三个二维码实体类这里要额外说一个事情,第一个查询映射的方法,是干什么的首先上面参数有说过,二维码可携带参数有scene_id 和scene_str 但是临时二维码 只能用ID(关乎于后面的事件推送) 并且是32位非零整型,长度有限制,所以个人做了个参数映射,生成二维码码的参数在数据库关联一个ID,每次ID自增,每次传参要查询是否有对应的ID,没有就生成一个新的这部分逻辑很简单先不上代码了,如不需要,可自行注释代码,有需要可能后面会补。
这样我们就拿到了二维码的ticket
获取二维码就很简单了 通过访问链接就可以直接拿到二维码 官方是这么写的: HTTP GET请求(请使用https协议)https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET 提醒:TICKET记得进行UrlEncode ticket正确的情况下,状态码200,是一张图片可以下载。错误的话可能是404这里额外再说一句,那个携带参数,即使是它不支持或者超出限制了,二维码仍然会正常返回,但是参数不会正常携带到后面的事件里面
二、事件接收以及消息推送
首先说事件接收,这个事件接收是一个很广的概念,可以接收很多类型的事件,官方是这么写的




事件到了 我们需要做处理
这里返回的不是模版消息,是客服消息 看官方文档
发送文本消息时,支持插入跳小程序的文字链文本内容点击跳小程序说明: 1.data-miniprogram-appid 项,填写小程序appid,则表示该链接跳小程序; 2.data-miniprogram-path项,填写小程序路径,路径与app.json中保持一致,可带参数; 3.对于不支持data-miniprogram-appid 项的客户端版本,如果有herf项,则仍然保持跳href中的网页链接; 4.data-miniprogram-appid对应的小程序必须与公众号有绑定关系。
下一篇详细介绍怎么回消息以及代码~
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2025年03月14日 18时54分12秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
java —— static 关键字
2019-03-03
在 Python 调试过程中设置不中断的断点 | Linux 中国
2019-03-03
使用开源可视化工具来理解你的 Python 代码 | Linux 中国
2019-03-03
硬核观察 | 有人在比特币骗局中损失了 10 个比特币
2019-03-03
使用 top 命令了解 Fedora 的内存使用情况 | Linux 中国
2019-03-03
8皇后问题 递归 函数调用是重点
2019-03-03
1541 +1 *2 ²
2019-03-03
面试别慌!阿里专家带你从【入门+基础+进阶+项目】攻破SpringBoot
2019-03-03
【Java面试】30个 Java 集合面试必备的问题和答案
2019-03-03
华为鸿蒙到底是不是安卓系统套了个壳?
2019-03-03
fragment中recyclerview的重新加载问题
2019-03-03
window程序设计(1):第一个windows程序
2019-03-03
windows程序设计(4):文本输出
2019-03-03
21.2.3总结
2019-03-03
线性代数和数学期望杂题
2019-03-03
【SSL_P2876】2017年东莞市信息学特长生测试题 工程
2019-03-03
【洛谷_P1433】吃奶酪
2019-03-03
volatile关键字和AtomicInteger
2019-03-03