|
为了满足用户渠道推广分析和用户帐号绑定等场景的需要,公众平台提供了生成带参数二维码的接口。使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送。
目前有2种类型的二维码:
1、临时二维码,是有过期时间的,最长可以设置为在二维码生成后的30天(即2592000秒)后过期,但能够生成较多数量。临时二维码主要用于帐号绑定等不要求二维码永久保存的业务场景 2、永久二维码,是无过期时间的,但数量较少(目前为最多10万个)。永久二维码主要用于适用于帐号绑定、用户来源统计等场景。
用户扫描带场景值二维码时,可能推送以下两种事件:
如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。
如果用户已经关注公众号,在用户扫描后会自动进入会话,微信也会将带场景值扫描事件推送给开发者。
获取带参数的二维码的过程包括两步,首先创建二维码ticket,然后凭借ticket到指定URL换取二维码。
参数说明
| 参数 | 说明 |
| expire_seconds |
该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 |
| action_name |
二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值 |
| action_info |
二维码详细信息 |
| scene_id |
场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000) |
| scene_str |
场景值ID(字符串形式的ID),字符串类型,长度限制为1到64 |
返回说明
正确的Json返回结果:
| 参数 | 说明 |
| ticket |
获取的二维码ticket,凭借此ticket可以在有效时间内换取二维码。 |
| expire_seconds |
该二维码有效时间,以秒为单位。 最大不超过2592000(即30天)。 |
| url |
二维码图片解析后的地址,开发者可根据该地址自行生成需要的二维码图片 |
通过ticket换取二维码
获取二维码ticket后,开发者可用ticket换取二维码图片。请注意,本接口无须登录态即可调用。
请求说明
一、新建一个QrCodeUtil里面包含三个方法,分别是封装请求的参数,产生二维码和获得二维码
QrCodeUtil.java
package com.xu.wemall.components.weixin;
import com.alibaba.fastjson.JSONObject; import com.xu.wemall.commons.constants.URIConstant; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate;
import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.TreeMap;
@Slf4j @Component public class QrCodeUtil {
@Autowired private RestTemplate restTemplate;
@Autowired private AccessTokenUtil accessTokenUtil;
private String createQrCodeString(String sceneStr) {
TreeMap<String, String> params = new TreeMap<>(); // output data JSONObject data = new JSONObject(); data.put("action_name", "QR_SCENE"); data.put("expire_seconds", 3600);//一小时
JSONObject scene = new JSONObject(); scene.put("scene_str", sceneStr); JSONObject actionInfo = new JSONObject(); actionInfo.put("scene", scene); data.put("action_info", actionInfo);
return data.toJSONString();
}
public JSONObject createQrCode(String sceneId) {
String qrCodeString = this.createQrCodeString(sceneId); log.info("qrCodeString:{}", qrCodeString);
String accessToken = accessTokenUtil.getAccessToken(); if (accessToken != null) { log.info("URL{}", URIConstant.CREATE_QRCODE_URL); String url = URIConstant.CREATE_QRCODE_URL.replace("ACCESS_TOKEN", accessToken); log.info("URL_ACCESS_TOKEN:{}", url); //将菜单对象转换成JSON字符串
//发起POST请求创建菜单 JSONObject jsonObject = restTemplate.postForObject(url, qrCodeString, JSONObject.class);
return jsonObject; } return null;
}
public void showQrCode(String ticket) throws UnsupportedEncodingException {
String TICKET = URLEncoder.encode(ticket, "utf-8");
log.info("URL{}", URIConstant.SHOW_QRCODE_URL); String url = URIConstant.SHOW_QRCODE_URL.replace("TICKET", TICKET); log.info("SHOW_QRCODE_URL:{}", url); //将菜单对象转换成JSON字符串
//发起POST请求创建菜单 restTemplate.getForObject(url, JSONObject.class);
}
}
二、我们新建一个controller用来提交我们的请求
QrCodeWxController.java
package com.xu.wemall.controller.weixin;
import com.alibaba.fastjson.JSONObject; import com.xu.wemall.components.weixin.QrCodeUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController;
import java.io.UnsupportedEncodingException;
/** * 类名称: LoginController * 类描述: 与微信对接登陆验证 * * @author yuanjun * 创建时间:2017年12月5日上午10:52:13 */ @Slf4j @RestController @Api(tags = "微信生成带参的二维码接口") @RequestMapping(value = "/weixin/qrcode") public class QrCodeWxController {
@Autowired private QrCodeUtil qrCodeUtil;
@ApiOperation(value = "创建带参的二维码") @RequestMapping(value = "/createQrCode", method = RequestMethod.POST) public Object createQrCode(String sceneId) {
JSONObject jsonObject = qrCodeUtil.createQrCode(sceneId); return jsonObject;
}
@ApiOperation(value = "获取带参的二维码") @RequestMapping(value = "/showQrCode", method = RequestMethod.GET) public void showQrCode(String ticket) throws UnsupportedEncodingException { qrCodeUtil.showQrCode(ticket);
}
}
三、我们打开我们的swagger页面提交一下请求试试看
四、根据ticket获取二维码
https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQEd7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyYlo5NXRyR0ljZ2oxOFVkZHh1MWQAAgQofw1eAwQQDgAA
五、【One More Thing!!!】
那这个二维码别人扫了我们怎么知道呢?回答:如果别人扫了我们生成的二维码就会触发我们的扫码事件,微信服务器就会给我们推送如下的消息包
到这里你应该清楚了吧,我们在我们的微信对接接口的POST方法里增加如下代码即可:
WeiXinController.java
package com.xu.wemall.controller.weixin;
import com.alibaba.fastjson.JSONObject; import com.xu.wemall.commons.utils.CheckUtil; import com.xu.wemall.components.weixin.MessageUtil; import com.xu.wemall.components.weixin.WeiXinUserUtil; import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.util.Map;
/** * 类名称: LoginController * 类描述: 与微信对接登陆验证 * * @author yuanjun * 创建时间:2017年12月5日上午10:52:13 */ @Slf4j @RestController @Api(tags = "接入验证接口") @RequestMapping(value = "/weChart") public class WeiXinController {
@Autowired private WeiXinUserUtil weiXinUserUtil;
@Autowired private MessageUtil messageUtil;
@RequestMapping(value = "/connect", method = RequestMethod.GET) public String connect(@RequestParam(value = "signature") String signature, @RequestParam(value = "timestamp") String timestamp, @RequestParam(value = "nonce") String nonce, @RequestParam(value = "echostr") String echostr) {
log.info("-----开始校验签名-----"); PrintWriter out = null; if (CheckUtil.checkSignature(signature, timestamp, nonce)) { log.info("-----签名校验通过-----"); return echostr; } else { log.info("-----校验签名失败-----"); return null; }
}
@RequestMapping(value = "connect", method = RequestMethod.POST) public String dopost(HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setCharacterEncoding("utf-8");
//将微信请求xml转为map格式,获取所需的参数 Map<String, String> map = MessageUtil.parseXml(request); String ToUserName = map.get("ToUserName"); String FromUserName = map.get("FromUserName"); String MsgType = map.get("MsgType"); String Content = map.get("Content"); String Event = map.get("Event");
if(MessageUtil.REQ_MESSAGE_TYPE_EVENT.equals(MsgType)){
if(MessageUtil.EVENT_TYPE_SUBSCRIBE.equals(Event)){ String xmlString = messageUtil.subscribeForText(ToUserName,FromUserName);
//关注了公众号,调用接口获得用户的详细信息并保存到后台 JSONObject jsonObject = weiXinUserUtil.handdleWeixinUserInfo(FromUserName); log.info("获取用户的详细信息:{}",jsonObject.toJSONString());
return xmlString;
}else if(MessageUtil.EVENT_TYPE_UNSUBSCRIBE.equals(Event)){
String xmlString = messageUtil.unsubscribeForText(ToUserName,FromUserName); return xmlString;
}else if(MessageUtil.EVENT_TYPE_SCAN.equals(Event)){ JSONObject jsonObject = weiXinUserUtil.handdleWeixinUserInfo(FromUserName); log.info("获取用户的详细信息:{}",jsonObject.toJSONString());
}
}
//处理文本类型,实现输入1,回复相应的封装的内容 if (MessageUtil.REQ_MESSAGE_TYPE_TEXT.equals(MsgType)) { String xmlString = messageUtil.replyForText(ToUserName,FromUserName,"你发送的是:" + Content); log.info(xmlString); return xmlString;
}
if (MessageUtil.REQ_MESSAGE_TYPE_IMAGE.equals(MsgType)) {
String filePath = "C:\\Users\\RonnieXu\\Pictures\\2.jpg"; String xmlString = messageUtil.replyForImage(ToUserName,FromUserName,filePath); return xmlString; }
return null; }
}
WeiXinUserUtil.java
package com.xu.wemall.components.weixin;
import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.xu.wemall.commons.constants.URIConstant; import com.xu.wemall.entry.WxUser; import com.xu.wemall.service.IWxUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate;
@Slf4j @Component public class WeiXinUserUtil {
@Autowired private IWxUserService iWxUserService;
@Autowired private RestTemplate restTemplate;
@Autowired private AccessTokenUtil accessTokenUtil;
public JSONObject handdleWeixinUserInfo(String openId) {
String accessToken = accessTokenUtil.getAccessToken(); if (accessToken != null) { log.info("URL{}", URIConstant.OPENID_USERINFO_URL); String url = URIConstant.OPENID_USERINFO_URL.replace("ACCESS_TOKEN", accessToken) .replace("OPENID", openId); log.info("OPENID_USERINFO_URL:{}", url);
//发起POST请求创建菜单 JSONObject jsonObject = restTemplate.getForObject(url, JSONObject.class);
//表示订阅了该公众号 if (jsonObject.getIntValue("subscribe") == 1) { //保存 WxUser wxUser = JSONObject.parseObject(jsonObject.toJSONString(), WxUser.class);
//先查一下是否曾经查询过(查看数据库数据) QueryWrapper<WxUser> queryWrapper = new QueryWrapper(); queryWrapper.lambda().eq(WxUser::getOpenid, openId); WxUser wxUserExist = iWxUserService.getOne(queryWrapper); if (wxUserExist == null) { boolean result = iWxUserService.saveOrUpdate(wxUser); }
}
return jsonObject; }
return null; }
}
打完收工,下回再见!
========================================================================================================================================================================================================
如果您觉得此文有帮助,可以小小打赏一下,持续更新更有动力哟!
来源:https://www.cnblogs.com/xulijun137/p/12213604.html |