本文已参与「新人创作礼」活动,一起开启掘金创作之路
在微信开发的过程中,在业务上常常会有分享的需求,而二维码给分享提供了比较快捷便利的解决方案。下面来看一下在微信公众号中二维码是如何生成的。
首先我们开始老样子先去微信公众平台中查看一下文档,首先进入文档中心,在左侧菜单中账号管理>生成带参数的二维码。然后我们大致看下业务场景
从这里可以比较清楚看到,这个api的二维码应用于推广分享,然后有临时和永久两种。这两个的区别也比较明显,临时就是有过期时间,你生成的码过段时间就不能用了,但是生成数量上比永久的多。永久的有10万个如果业务使用量不大,可以选永久。这里微信还提供了事件推送,本文就不展开这个功能了。
首先第一步得到一个二维码ticket,这个主要就是一个换取凭证的过程,可以类别于坐高铁的车票。我们看下这个api
这里的32位是指二进制数,按照你想传参的类型选则是id还是str,通过action_name可以决定二维码是否是永久的,下面是参数json结构
{
"action_info": {
"scene": {
"scene_id": 12
}
},
"action_name": "QR_SCENE",
"expire_seconds": 7200
}
我们可以把这些信息看作是你买高铁票时的班次,座位等。那么现在开始获取ticket(买票)。记住不要忘记带上我们的access_token。这个是我们公众号的凭证,就像你买票时用的身份证一样
https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
发送post请求,部分代码清单
/**
* @description 公众号二维码ticket
* @author zhou
* @param sceneId 场景值id
* @param sceneStr 场景值字符串
* @param state 类型(临时/永久 0/1)
* @return ticketJson
* @date 2019/6/15
*/
@Override
public JSONObject QrCodeOfficialTicket(Integer sceneId, String sceneStr, Integer state) {
//拼装url
StringBuilder sb = new StringBuilder(WxOaUrlConfig.API_CREATE_QR_CODE);
sb.append("access_token=").append(redisUtil.get(CacheParam.OA_ACCESS_TOKEN));
String url = sb.toString();
JSONObject jsonObject = generateOfficialQrCodeJson(sceneId,sceneStr,state);
log.debug(jsonObject.toJSONString());
JSONObject resultJson = httpUtil.dePostJson(jsonObject, url);
if(resultJson.containsKey("ticket")){
return resultJson;
}else {
log.error("获取公众号二维码ticket失败,{}",resultJson.toJSONString());
throw new WeChatOaException(WeChatOaErrorEnum.QR_CODE_TICKET_ERROR);
}
}
如果成功会有下面的返回值,如果时永久的就没有过期时间字段。
{ "ticket":"gQHM7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyX2U2N3M3Y2VmYkMxWW5US3h1Y28AA
gT32u5eAwQgHAAA",
"expire_seconds": 7200,
"url": "http://weixin.qq.com/q/02_e67s7cefbC1YnTKxuco"
}
那么第二步就是获取二维码的图片,(也就是我们要凭票上车了)。这里需要我们调用微信的api同时接收它返回的图片格式
首先是api,非常简单
HTTP GET请求(请使用https协议)mp.weixin.qq.com/cgi-bin/sho… 提醒:TICKET记得进行UrlEncode。
那么上代码
public void generateQrCodeOfficial(JSONObject ticketJson, HttpServletResponse response) {
StringBuilder sb = new StringBuilder(WxOaUrlConfig.API_SHOW_QR_CODE);
try {
sb.append("ticket=").append(URLEncoder.encode(ticketJson.getString("ticket"),"utf-8"));
String url =sb.toString();
httpUtil.getImage(response,url);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
首先是拼接url,然后发送请求,这里设置响应的格式,同时用 字节流进行输出
public void getImage(HttpServletResponse response,String url){
try {
URL u = new URL(url);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod("GET");
InputStream inputStream = conn.getInputStream();
byte[] bytes = readInputStream(inputStream);
inputStream.close();
response.setContentType("image/jpg");
OutputStream outputStream = response.getOutputStream();
outputStream.write(bytes);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private byte[] readInputStream(InputStream inputStream) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) != -1){
outputStream.write(buffer,0,len);
}
inputStream.close();
return outputStream.toByteArray();
}
然后调用结果就是这样的。好了大家一起愉快的买票上车吧
\