微信小程序二維碼


一、獲取小程序碼的三個接口

不同的接口對應不同的業務場景,接口B用的較多,接口C官方不推薦使用,也就是說根據需碼量來決定選擇A接口還是B接口。

(1)、接口 A: 適用於需要的碼數量較少的業務場景
生成小程序碼,可接受 path 參數較長,生成個數受限

接口A文檔

(1)、接口 B:適用於需要的碼數量極多的業務場景
生成小程序碼,可接受頁面參數較短,生成個數不受限.

接口B文檔

就以接口B來展開說明

二、思路介紹

(1)、獲取 ACCESS_TOKEN 憑證。

image

獲取Access token 文檔

根據文檔可以看出來,一個Token最多可用2小時並且只能存在一個可用Token,即使本Token並沒有失效,再次獲取新的Token也會使上一個Token失效。

為了保證高可用,不能2小時刷新一次token吧,太呆逼。可以1個半小時刷新一次,獲取Token存入Redis,如果Redis中獲取不到就重新獲取Token存入Redis。

(2)、帶參入碼

請求方式
POST https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=你的微信Token

參數
image

常用的有 scenepage 其他的具體細節並不做過多控制

scene傳參有些許特殊

{
 "scene": "a=1"
}

多個參數 :scene=shop=382number=3這樣傳 有的手機就把 = 轉義了,有的沒有,所以定義統一解析規則 a=1 改為 az1 或者 ak1等等 由前端去拆分字符解析

(3)、保存圖片

操作成功后 返回的圖片 Buffer 而不是圖片地址,因此需要做一些處理,保存到本地、然后上傳到服務器

(4)、異常處理

失敗的話會返回錯誤碼,根據具體的錯誤碼去做處理
image

如果是Token失效所導致的異常40001,就在獲取一遍Token重新執行操作,提高容錯率,保證高可用

三、編碼

(1)、獲取 ACCESS_TOKEN 憑證。

開發環境一般都有配置Redis頭,實例代碼並不規范,僅供參考。

    //從Yml配置文件讀取關於微信的配置
    @Resource
    private WechatConfig wxConfig;
    
    @Override
    public String getWeChatToken() throws IOException {
        //1、從Redis獲取微信的Token
        String accessToken = RedisHelper.get(RedisKey.getKey("存入的微信Token"));
        //2、不為空則返回Redis中的微信Token
        if (StringUtils.isNotBlank(accessToken)) {
            return accessToken;
        }
        //3、為空則獲取Token
        accessToken = this.obtainToken();
        return accessToken;
    }

    /**
     * 獲取 access_token
     */
    @Override
    public synchronized String obtainToken() throws IOException {
        //1、從配置文件讀取到下面的參數 並發送Get請求就可以獲取到Token
        String getToken = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
        //2、獲取到請求的結果轉成指定的格式
        //(接口只返回access_token和錯誤碼expires_in,因此該param只封裝這兩個參數)
        returnTokenParam token = JSONObject.parseObject(s, returnTokenParam .class);
        String accessToken = token .getAccessToken();
        //3、獲取Token成功存入Redis 失敗拋出異常,當然也可以做異常處理
        if ("".equals(accessToken) || StringUtils.isBlank(accessToken)) {
            log.error("獲取微信Access_Token失敗");
            throw new BizException(ErrorCode.WECHAT_ACCESSTOKEN_ERROR);
        }
        RedisHelper.set(token自定義名稱, accessToken, 過期時間 60*60*30 1個半小時);
        return accessToken;
    }

(2)、帶參入碼、異常處理

        //1、校驗,准備參數
        //因Token只能生效一個所以 非線上環境不去獲取token
        //(邏輯~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)
        //生成的用戶邀請小程序碼會被持久化,查詢是否持久化,是的話返回結果
        //(邏輯~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)
        //獲取微信accessToken
        String accessToken = 第一步的getWeChatToken();
        
        //2、創建請求參數
        JSONObject params = new JSONObject();
        //讓前端通過 "y" 解析參數  也可以是別的
        params.put("scene","cy"+customer.getRecommendCode());
        //掃碼后進入小程序的頁面位置(從yml讀)
        params.put("page", page);

        //3、發起 post json請求 (按自己的方式發請求,接收結果就行)
        Response response = 你自己的請求工具類.POST請求("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken, params);

        //4、獲取結果進行處理(成功默認返回image/jpeg)
        String contentType = response.header("Content-Type");
        if (!"image/jpeg".equals(contentType)) {
            //處理錯誤(獲取返回結果的body)
            String body = response.body().string();
            JSONObject jsonObject = new JSONObject(body);
            String errcode = jsonObject.get("errcode").toString();
            //如果為 40001 錯誤碼 極可能是token出現問題,保證高可用再去重新獲取
            if (!"40001".equals(errcode)) {
                String errmsg = jsonObject.get("errmsg").toString();
                log.error("記錄錯誤日志");
                //拋出異常
                throw new .....;
            }
            //重新獲取token
            accessToken = 第一步的getWeChatToken();
            //重新發起 post json請求
            Response response = 你自己的請求工具類.POST請求("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken, params);
            //獲取結果進行處理
            contentType = response.header("Content-Type");
            if (!"image/jpeg".equals(contentType)) {
                String errmsg = jsonObject.get("errmsg").toString();
                log.error("記錄錯誤日志");
                //拋出異常
                throw new .....;
            }
        }

        //5、保存圖片
        saveToImgByInputStream(得到的流,保存路徑)
        //上傳到服務器
        //(邏輯~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)
        //持久化圖片地址
        //(邏輯~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)

3、保存圖片

/**
     * 將二進制轉換成文件保存
     * @param instreams 二進制流
     * @param imgPath 圖片的保存路徑
     * @return
     *      1:保存正常
     *      0:保存失敗
     */
    public static int saveToImgByInputStream(InputStream instreams, String imgPath){
        int stateInt = 1;
        if(instreams != null){
            try {
                //可以是任何圖片格式.jpg,.png等
                File file = new File(imgPath);
                FileOutputStream fos=new FileOutputStream(file);
                byte[] b = new byte[1024];
                int nRead = 0;
                while ((nRead = instreams.read(b)) != -1) {
                    fos.write(b, 0, nRead);
                }
                fos.flush();
                fos.close();
            } catch (Exception e) {
                stateInt = 0;
                e.printStackTrace();
            }
        }
        //1 成功,0 失敗
        return stateInt;
    }

一定不能忘了,微信Token只能同時存在一個,且過期時間默認走最大時間(2小時)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM