1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 08. 微信公众号生成带参数二维码

08. 微信公众号生成带参数二维码

时间:2020-07-16 15:25:49

相关推荐

08. 微信公众号生成带参数二维码

1.官网

为了满足用户聚到推广分析、用户账号绑定等场景需要,可以生成不同场景值的二维码

目前有两种类型二维码

临时二维码

有过期时间,最长可以设置为在二维码生成后的30天(即2592000秒)后过期数量不限制临时二维码主要用于帐号绑定等不要求二维码永久保存的业务场景

永久二维码

无过期时间数量较少(目前为最多10万个)主要用于适用于帐号绑定、用户来源统计等场景

创建

接口

https://api./cgi-bin/qrcode/create?access_token=TOKEN

接口请求体参数示例

{"expire_seconds": 2592000,"action_name": "QR_STR_SCENE","action_info": {"scene": {"scene_str": "zxcvbnm"}}}

返回

正确

{"ticket": "gQHo8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyVWNqM3BtRmFjVEgxN0hmWTF4MUoAAgTrwhRhAwQAjScA","expireSeconds": 2592000,"url": "/q/02Ucj3pmFacTH17HfY1x1J"}

ticket,可以用来作为参数调用微信接口GET请求https://mp./cgi-bin/showqrcode?ticket=TICKET获取该二维码(TICKET记得进行UrlEncode)ticket正确情况下,http返回码是200,是一张图片,可以直接展示或者下载错误情况下(如ticket非法)返回HTTP错误码404url,用这个 url 生成的二维码图片与 根据ticket调微信服务器接口获得二维码图片一致,扫码关注之后的事件推送一致。

错误

{"errCode": null,"errMsg": null}

用户扫码关注公众号后的事件推送

如果用户未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。

<xml><ToUserName><![CDATA[gh_51a674c7e13c]]></ToUserName><FromUserName><![CDATA[oqUo360zkIEFzJRcrxCn6MfZhah0]]></FromUserName><CreateTime>1628733211</CreateTime><MsgType><![CDATA[event]]></MsgType><Event><![CDATA[subscribe]]></Event><EventKey><![CDATA[qrscene_ceshi]]></EventKey><Ticket><![CDATA[gQFc8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyM0xpZ29qRmFjVEgxMkI2WTF4Y3gAAgSleRRhAwQAjScA]]></Ticket></xml>

EventKeyqrscene_+ 创建二维码时的scene_id 或 scene_strTicket是创建二维码时返回的,可以用作参数获取二维码

如果用户已经关注公众号,在用户扫描后会自动进入会话,微信也会将带场景值扫描事件推送给开发者。

<xml><ToUserName><![CDATA[gh_51a674c7e13c]]></ToUserName><FromUserName><![CDATA[oqUo36wMcs4NW1Tpjl_LcUKPmauY]]></FromUserName><CreateTime>1628732049</CreateTime><MsgType><![CDATA[event]]></MsgType><Event><![CDATA[SCAN]]></Event><EventKey><![CDATA[ceshi]]></EventKey><Ticket><![CDATA[gQFc8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyM0xpZ29qRmFjVEgxMkI2WTF4Y3gAAgSleRRhAwQAjScA]]></Ticket></xml>

EventSCANEventKey是创建二维码时的scene_id 或 scene_str

2. 实现

WxQrCodeBean.java

import cn.hutool.core.util.StrUtil;import com.fasterxml.jackson.annotation.JsonProperty;import lombok.Data;import java.io.Serializable;import java.util.HashMap;import java.util.Map;import java.util.Objects;/*** 生成 二维码 所需参数** @author sheng_zs@* @date -08-11 16:13*/@Datapublic class WxQrCodeBean implements Serializable {/*** 该二维码有效时间,以秒为单位。 最大不超过 2592000(即30天)<br>* 此字段如果不填,则默认有效期为30秒。*/@JsonProperty("expire_seconds")private Integer expireSeconds;/*** 二维码类型* <ol>* <li>QR_SCENE为临时的整型参数值</li>* <li>QR_STR_SCENE为临时的字符串参数值</li>* <li>QR_LIMIT_SCENE为永久的整型参数值</li>* <li>QR_LIMIT_STR_SCENE为永久的字符串参数值</li>* </ol>*/@JsonProperty("action_name")private String actionName;/*** 二维码详细信息*/@JsonProperty("action_info")private ActionInfo actionInfo;/*** 初始化,获取 scene_str 对象** @param isTemporary 是否是临时二维码* @param sceneId 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)* @param expireSeconds 过期时间,最大不超过 2592000,如果不是临时二维码,则要求为 null* @return {@link WxQrCodeBean}*/public static WxQrCodeBean getSceneIdInstance(boolean isTemporary, Integer sceneId, Integer expireSeconds) {// 参数判断final boolean flag =(isTemporary && ((Objects.isNull(expireSeconds) || expireSeconds > 2592000 || expireSeconds <= 0)))|| (!isTemporary && (Objects.nonNull(expireSeconds) || sceneId > 100000 || sceneId < 1));if (flag) {throw new IllegalArgumentException("生成二维码参数有误!");}WxQrCodeBean codeBean = new WxQrCodeBean();codeBean.setExpireSeconds(expireSeconds);codeBean.setActionName(isTemporary ? "QR_SCENE" : "QR_LIMIT_SCENE");codeBean.setActionInfo(ActionInfo.getSceneId(sceneId));return codeBean;}/*** 初始化,获取 scene_str 对象** @param isTemporary 是否是临时二维码* @param sceneStr场景值ID(字符串形式的ID),字符串类型,长度限制为1到64* @param expireSeconds 过期时间,最大不超过 2592000,如果不是临时二维码,则要求为 null* @return {@link WxQrCodeBean}*/public static WxQrCodeBean getSceneStrInstance(boolean isTemporary, String sceneStr, Integer expireSeconds) {// 参数判断final boolean flag =(isTemporary && (Objects.isNull(expireSeconds) || expireSeconds > 2592000 || expireSeconds <= 0))|| (!isTemporary && Objects.nonNull(expireSeconds)) || StrUtil.isBlank(sceneStr);if (flag) {throw new IllegalArgumentException("生成二维码参数有误!");}WxQrCodeBean codeBean = new WxQrCodeBean();codeBean.setExpireSeconds(expireSeconds);codeBean.setActionName(isTemporary ? "QR_STR_SCENE" : "QR_LIMIT_STR_SCENE");codeBean.setActionInfo(ActionInfo.getSceneStr(sceneStr));return codeBean;}@Datastatic class ActionInfo {/*** scene*/private Map<String, Object> scene;/*** 初始化,获取 scene_id 对象** @param sceneId scene_id* @return {@link ActionInfo}*/static ActionInfo getSceneId(Integer sceneId) {ActionInfo info = new ActionInfo();Map<String, Object> map = new HashMap<>(1);map.put("scene_id", sceneId);info.setScene(map);return info;}/*** 初始化,获取 scene_str 对象** @param sceneStr scene_str* @return {@link ActionInfo}*/static ActionInfo getSceneStr(String sceneStr) {ActionInfo info = new ActionInfo();Map<String, Object> map = new HashMap<>(1);map.put("scene_str", sceneStr);info.setScene(map);return info;}}}

WxTicketBean.java

import com.fasterxml.jackson.annotation.JsonAlias;import com.small.nine.wxmp.domain.bean.wx.WxErrorMsgBean;import lombok.Data;import lombok.EqualsAndHashCode;/*** 微信生成永久、临时二维码返回的 ticket 对象** @author sheng_zs@* @date -08-11 16:07*/@Data@EqualsAndHashCode(callSuper = true)public class WxTicketBean extends WxErrorMsgBean {private static final long serialVersionUID = 1L;/*** 获取的二维码ticket,凭借此ticket可以在有效时间内换取二维码。*/private String ticket;/*** 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天)。*/@JsonAlias("expire_seconds")private Integer expireSeconds;/*** 二维码图片解析后的地址,开发者可根据该地址自行生成需要的二维码图片<br>* 就是用这个地址生成 二维码 的二维码图片与 根据 ticket 调微信服务器接口获得二维码图片一致*/private String url;}

serviceImpl

@Overridepublic WxTicketBean createTemporaryQrCode() {final String url = String.format(WxConstant.URL_QR_CODE_CREATE_POST, getAccessToken());// 生成最大失效时间 临时二维码String post = HttpUtil.post(url, JsonUtils.writeValueAsString(WxQrCodeBean.getSceneStrInstance(true, UUID.randomUUID().toString(), 2592000)));return JsonUtils.readValue(post, WxTicketBean.class);}@Overridepublic void getQrCode(HttpServletResponse response) {/*final String url = String.format(WxConstant.URL_SHOW_QR_CODE_GET, "gQFc8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyM0xpZ29qRmFjVEgxMkI2WTF4Y3gAAgSleRRhAwQAjScA");try {response.reset();// 需要指定文件名的编码方式为 ISO-8859-1,否则会出现文件名中的中文字符丢失的问题response.addHeader("Content-Disposition", "attachment;filename=" + new String("测试临时二维码.png".getBytes("gb2312"), StandardCharsets.ISO_8859_1));// 设置响应内容类型为图片response.setContentType("image/png");long download = HttpUtil.download(url, new BufferedOutputStream(response.getOutputStream()), true);} catch (IOException e) {log.error("生成二维码失败:{}", e.getMessage());log.error("", e);}*/BufferedOutputStream stream = null;try {response.reset();// 需要指定文件名的编码方式为 ISO-8859-1,否则会出现文件名中的中文字符丢失的问题response.addHeader("Content-Disposition", "attachment;filename=" + new String("测试临时二维码.png".getBytes(), StandardCharsets.ISO_8859_1));// 设置响应内容类型为图片response.setContentType("image/png");// "/q/023LigojFacTH12B6Y1xcx" 是生成二维码时返回的 urlBufferedImage image = QrCodeUtil.generate("/q/023LigojFacTH12B6Y1xcx", 300, 300);ImageIO.write(image, "png", stream = new BufferedOutputStream(response.getOutputStream()));} catch (IOException e) {log.error("生成二维码失败:{}", e.getMessage());log.error("", e);} finally {if (Objects.nonNull(stream)) {try {stream.flush();stream.close();} catch (IOException e) {log.error("生成二维码关闭流失败!");}}}}

源码

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。