java+vue element 小程序碼後端生成和前端展示

java+vue element 小程序碼後端生成和前端展示

介紹下應用場景

技術框架:前端是vue+element 後端爲spring cloud,使用騰訊制碼接口類型B,使用restTemplate作爲請求框架。
業務場景: 前端查看某個頁面,本頁面生成小程序碼,將參數傳入小程序碼,用戶掃碼後查看頁面數據。(這個應該是通用場景吧)😅😅😅😅

接口介紹:

羅列幾個知識點:
1.小程序碼生成,騰訊分爲4種類型,詳細區別官方文檔裏解釋得很詳細,此處不再複述。
接口文檔鏈接
鏈接: 接口文檔.
此處我們選用接口B(無限數量,永久有效)。

java 後端

調用圖如下
後端調用流程
先請求接口憑證,獲取憑證後,再使用憑證去調用制碼接口,生成小程序碼。
後端代碼如下。
實體類,用於接收圖片

public class WxCodeUnlimitedResponseParam implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 請求失敗錯誤碼
     */
    private String errCode;

    /**
     * 請求失敗錯誤信息
     */
    private String errMsg;

    /**
     * 圖片信息
     */
    private byte[] buffer;

    public String getErrCode() {
        return errCode;
    }

    public void setErrCode(String errCode) {
        this.errCode = errCode;
    }

    public String getErrMsg() {
        return errMsg;
    }

    public void setErrMsg(String errMsg) {
        this.errMsg = errMsg;
    }

    public byte[] getBuffer() {
        return buffer;
    }

    public void setBuffer(byte[] buffer) {
        this.buffer = buffer;
    }
}

生成憑證

    /**
     * 獲取微信的appId的工具類,字符串之後需要JSON.parseObject轉化。
     *
     * @param appId
     * @param secret
     * @return 獲取結果
     */
    public static String getAccessToken(String appId, String secret) {
        String accesstoken="";
        String requestUrl = ACCESS_TOKEN_URL;
        //傳入參數替換
        requestUrl = requestUrl.replaceAll("APPID", appId);
        requestUrl = requestUrl.replaceAll("SECRET", secret);
        //超時,需要重新請求接口
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.getForObject(requestUrl, String.class);
        JSONObject jsonObject = JSON.parseObject(result.toString());
        accesstoken = jsonObject.getString("access_token");
        return result;
    }

注意

此處是簡單可用代碼,實際上獲取憑證後我們應該將憑證保存在我們數據庫中,原因是接口憑證一天有調用次數上限,且兩小時後失效。我們需要在調用前檢查數據庫中得憑證是否過期,過期後再重新請求新的憑證,而不是每次都去請求。
實際上正確的做法是使用redis保存accessToken(憑證),之後再起定時任務去專門維護此憑證。這樣得做法可避免高併發下得髒讀等問題(項目沒用redis,放棄)。

//生成二維碼接口

public static WxCodeUnlimitedResponseParam getUnlimitedCode(String accessToken, String scene, String page) {
        // url請求參數值
        Map<String, Object> params = new HashMap<String, Object>();
        //**注意:接口文檔錯誤需要將access_token參數放到url中,否則請求會失敗
		//scene爲你需要傳入得參數類似“id=????&code=222”,爲參數名和值組成得字符串。
        params.put("scene", scene);
        params.put("page", page);
        params.put("width", 200);
        params.put("auto_color", true);
        params.put("line_color", null);
        params.put("is_hyaline", false);

        byte[] byteArray = null;
        /** 第一種方式:使用RestTemplate。項目採用了這種方式。 **/
        // 調用微信接口
        WxCodeUnlimitedResponseParam res = new WxCodeUnlimitedResponseParam();
        try {
            RestTemplate restTemplate = new RestTemplate();
            String request =WX_CODE_URL.replaceAll("AccessToken",accessToken);
            ResponseEntity<byte[]> entity = restTemplate.postForEntity(
                    request,
                    JSONObject.toJSONString(params), byte[].class);
            // 如果你十分確認微信正確返回了圖片,那麼byteArray已經是你想要的結果了。
            byteArray = entity.getBody();
            // 微信返回內容,byte[]轉爲string
            String wxReturnStr = new String(byteArray);
            if (wxReturnStr.indexOf("errcode") != -1) {
                JSONObject json = JSONObject.parseObject(wxReturnStr);
                res.setErrCode(json.get("errcode").toString());
                res.setErrMsg(json.get("errmsg").toString());
            } else {
                res.setErrCode("0");
                res.setErrMsg("ok");
                res.setBuffer(byteArray);
            }
        } catch (Exception e) {
            LOGGER.error("微信小程序碼getUnlimited接口調用失敗", e);
        }
        return  res;
    }

此處之後整個後端請求流程就完成了,剩下的是如何返回給前端了。

前端

此處博主是以圖片流的方式返回給前端。
後端是這樣的

        String accessToken=wxacodeService.getAccessToken(type);
        WxCodeUnlimitedResponseParam res= wxacodeService.getUnlimited(accessToken,id,type);
        //以流的方式返回給前端
       InputStream inputStream = new ByteArrayInputStream(res.getBuffer());
        BufferedImage bufferedImage = ImageIO.read(inputStream);
        if (bufferedImage != null){
            String format = "jpg";
            return ImageIO.write(bufferedImage, format, response.getOutputStream());
        }

此處將圖片轉化流傳輸
前端有兩種方式獲取圖片
一種是將當前接口地址看作一種圖片資源鏈接
在 image組件中將src直接指向後端接口路徑。

  <div class="block">
    <span class="demonstration">默認</span>
    <el-image :src="QRcodeSrc"></el-image>
  </div>
      //獲取二維碼        
      getQRcode:function () {
              var appId ="";
              var secret ="ceshi";
              this.QRcodeSrc="/api/makeWxCode?appId="+appId+"&secret="+secret;
              }                               
            },

此處注意需要前臺在路由中允許訪問後臺任意路徑
路徑後爲/*
在這裏插入圖片描述
2.如果不允許可在前臺將流轉化爲圖片顯示
轉碼爲

   let params = {
        id: this.id,
      };
      axios({
        method: 'GET',
        url: '/api/makeWxCode',
        params: params,
        responseType: 'arraybuffer'
      })
      .then(res => {
        console.log(res);
        const bufferUrl = btoa(new Uint8Array(res.data).reduce((body, byte) => body + String.fromCharCode(byte), ''));
        this.QRcodeSrc = 'data:image/png;base64,' + bufferUrl;
        this.loading = false;
      })
      .catch(err => {
        this.$message('請求失敗!');
        this.loading = false;
      });

當然,此種做法,後臺就無需返回圖片流了,可以在最開始便返回byte[]圖片,此處做法應該與前端溝通,再根據情況選擇。

!!!拒絕搬運,創作不易,有幫助請點個贊

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章