java+vue element 小程序码后端生成和前端展示

  • 介绍下应用场景
  • 接口介绍:
  • java 后端
  • 注意
  • 前端


介绍下应用场景

技术框架:前端是vue+element 后端为spring cloud,使用腾讯制码接口类型B,使用restTemplate作为请求框架。
业务场景: 前端查看某个页面,本页面生成小程序码,将参数传入小程序码,用户扫码后查看页面数据。(这个应该是通用场景吧)😅😅😅😅

接口介绍:

罗列几个知识点:
1.小程序码生成,腾讯分为4种类型,详细区别官方文档里解释得很详细,此处不再复述。
接口文档链接
链接: 接口文档.
此处我们选用接口B(无限数量,永久有效)。

java 后端

调用图如下

java接收 微信小程序码 图片 java生成小程序码_Image


先请求接口凭证,获取凭证后,再使用凭证去调用制码接口,生成小程序码。

后端代码如下。

实体类,用于接收图片

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;
              }                               
            },

此处注意需要前台在路由中允许访问后台任意路径

路径后为/*

java接收 微信小程序码 图片 java生成小程序码_json_02


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[]图片,此处做法应该与前端沟通,再根据情况选择。