在微信開發的過程中,在業務上常常會有分享的需求,而二維碼給分享提供了比較快捷便利的解決方案。下面來看一下在微信公衆號中二維碼是如何生成的。
首先我們開始老樣子先去微信公衆平臺中查看一下文檔,首先進入文檔中心,在左側菜單中賬號管理>生成帶參數的二維碼。然後我們大致看下業務場景
從這裏可以比較清楚看到,這個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協議)https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET 提醒: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();
}
然後調用結果就是這樣的。好了大家一起愉快的買票上車吧