微信小程序03: 获取不限制的小程序二维码

全文目录,一步到位

  • 1.前言简介
    • 1.1 专栏传送门
      • 1.1.1 上文小总结
      • 1.1.2 上文传送门
  • 2. 获取不限制二维码操作
    • 2.1 准备工作
      • 2.1.1 请先复制00篇的统一封装代码
      • 2.1.2 修改配置文件中的参数
    • 2.2 具体代码使用与注释如下
      • 2.2.1 业务代码如下
      • 2.2.2 代码解释(一)[无需复制]
      • 2.2.3 创建Base64类
    • 2.3 运行并检查结果
      • 2.3.1 controller代码
      • 2.3.2 二维码请求对象dto代码
    • 2.4 异常总结与解决(相对全面)
      • 2.4.0 直接测试后发现问题
      • 2.4.1 (核心排查)使用微信官方接口测试查看问题
        • 导入curl数据方法(如图所示)
        • curl: 抓包数据如下(导入即可)
      • 2.4.2 解决方案
        • 异常一: (异常码41030)导入curl后, 报这个错误
        • 异常二: (异常码41030)无效的page参数(`很坑`)
        • 异常三: (异常码40169)scene过长无法生成
        • 异常N(`跳过`): 网络波动等访问超时/异常
      • 2.4.3 正确结果(微信扫码测试一下)
      • 2.4.4 接口请求测试
        • 特殊: 如果只能显示出一半
  • 3. 文章的总结与预告
    • 3.1 本文总结
    • 3.2 下文预告


1.前言简介

本篇细节很多, 我会在文章最后统一总结

1.1 专栏传送门

=> 小程序相关操作专栏 <=

1.1.1 上文小总结

上文主要是大多数微信小程序的整体封装, 代码共用, 而本篇只需要关心业务本身即可, 使用前请先复制上文的代码后使用(请看1.1.2文章传送门)

1.1.2 上文传送门

微信小程序00: 公共封装配置(核心篇)

2. 获取不限制二维码操作

2.1 准备工作

2.1.1 请先复制00篇的统一封装代码

这里强调一下

请先复制核心篇: ===> 微信小程序-00 小程序统一封装类
请先阅读上一篇: ===> 微信小程序01: springboot获取accessToken方式

2.1.2 修改配置文件中的参数

例如appid等, 均在
在这里插入图片描述

2.2 具体代码使用与注释如下

2.2.1 业务代码如下

AjaxResult统一返回值对象 随意写
第二步的userService代表您的业务, 随意写
记得@Autowired一下

    /**
     * 获取注册二维码
     *
     * @param wxCodeUnlimitedReqDTO 请求对象
     * @return AjaxResult
     */
    @SneakyThrows
    public AjaxResult getRegisterQrcode(WxCodeUnlimitedReqDTO wxCodeUnlimitedReqDTO) {

        //1.获取access_token
        String accessToken = wechatServiceUtils.getRedisCacheAccessToken();

        //2. 处理scene值
        String scene = userService.getUserRelationScene(wxCodeUnlimitedReqDTO);

        //3. 获取微信不限制二维码的input输入流
        InputStream inputStream = wechatServiceUtils.getUnlimitedWxQrCode(wxCodeUnlimitedReqDTO.setScene(scene), accessToken);

        //3. byte的nio流直接转换为base64
        String base64Str = Base64.changeInputIOToBase64A(inputStream);

        Map<String, String> map = new HashMap<>();
        map.put("imgBase64", "data:image/png;base64," + base64Str);
        map.put("scene", scene);

        //4. 返回结果
        return AjaxResult.success("操作成功!", map);
    }

2.2.2 代码解释(一)[无需复制]

wechatServiceUtils.getUnlimitedWxQrCode() 统一封装 获取不限制二维码操作
其中使用了restTemplate远程调用微信官方接口
通过ByteArrayInputStream直接将byte转换为InputStream

  • 这块还是有其他写法的 (import org.springframework.core.io.Resource;)
  • 这个能看到整个接口的返回信息 报错信息等 二选一即可
//方案二:(需要替换WechatServiceUtils类中对应方法)
ResponseEntity<Resource> responseEntity = restTemplate.exchange(wechatConfigProperties.getWxACodeUnLimitUrl(accessToken), HttpMethod.POST, new HttpEntity<>(params, headers), Resource.class);
log.info("==> 微信二维码返回参数: {} <==", responseEntity);
// 从响应体中获取输入流
InputStream inputStream = Objects.requireNonNull(responseEntity.getBody()).getInputStream();

微信文档位置: => 微信小程序获取不限制二维码 <=

 	/**
     * 生成小程序带参数二维码
     */
    @SneakyThrows
    public InputStream getUnlimitedWxQrCode(WxCodeUnlimitedReqDTO wxCodeUnlimitedReqDTO, String accessToken) {

        Map<String, Object> params = new HashMap<>();
        params.put("scene", wxCodeUnlimitedReqDTO.getScene());
        params.put("page", wxCodeUnlimitedReqDTO.getPage());
        params.put("path", wxCodeUnlimitedReqDTO.getPage());
        params.put("env_version", wxCodeUnlimitedReqDTO.getEnvVersion());
        params.put("width", wxCodeUnlimitedReqDTO.getWidth());
        params.put("auto_color", wxCodeUnlimitedReqDTO.getAutoColor());//自动配置线条颜色

        ResponseEntity<byte[]> response = restTemplate.postForEntity(wechatConfigProperties.getWxACodeUnLimitUrl(accessToken), JSON.toJSONString(params), byte[].class);
        System.out.println(JSON.toJSONString(params));

        byte[] buffer = response.getBody();
        assert buffer != null;
        return new ByteArrayInputStream(buffer);
    }

    /**
     * 远程调用 restTemplate方法 post请求
     */
    public <T> T sendPostRestTemplate(String url, Map<String, Object> body, Class<T> responseType) {
        return restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(body, null), responseType).getBody();
    }

2.2.3 创建Base64类

里面有几个方法 选一个即可 changeInputIOToBase64A()

 /**
     * 方法一: IO: 转换输入流->Base64
     * @param in
     * @return
     */
    public static String changeInputIOToBase64A(InputStream in) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理

        byte[] data = null;
        String encode = null; // 返回Base64编码过的字节数组字符串
        // 对字节数组Base64编码
        org.apache.commons.codec.binary.Base64 encoder = new org.apache.commons.codec.binary.Base64();
        try {
            // 读取图片字节数组
            data = new byte[in.available()];
            in.read(data);
            encode = encoder.encodeToString(data);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return encode;
    }


    /**
     * 方法二: IO: 转换输入流->Base64
     */
    public static String changeInputIOToBase64B(InputStream inputStream) {
        byte[] data = null;
        try (ByteArrayOutputStream swapStream = new ByteArrayOutputStream()) {
            byte[] buff = new byte[100];
            int rc = 0;
            while ((rc = inputStream.read(buff, 0, 100)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            data = swapStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return java.util.Base64.getEncoder().encodeToString(data);
    }
    
    /**
     * 关流功能
     *
     * @param inputStream 输入流
     * @throws IOException 异常
     */
    public static void closeInputStream(InputStream inputStream) throws IOException {
        try {
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2.3 运行并检查结果

2.3.1 controller代码

模拟-获取注册二维码

   /**
     * 获取注册二维码
     */
    @PostMapping("/getQrcode")
    public AjaxResult getQrcode(@RequestBody WxCodeUnlimitedReqDTO wxCodeUnlimitedReqDTO) {

        log.info("===> 获取注册二维码 <===");

        log.info(JSONObject.toJSONString(wxCodeUnlimitedReqDTO));

        return loginService.getQrcode(wxCodeUnlimitedReqDTO);
    }

2.3.2 二维码请求对象dto代码

微信生成不限制小程序二维码请求dto


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * 微信生成不限制小程序二维码请求dto
 * @author pzy
 * @version 0.1.0
 * @description: TODO
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class WxCodeUnlimitedReqDTO {
    /**
     * 最大32个可见字符,只支持数字,
     * 大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,
     * 其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
     */
    private String scene;

    /**
     * 页面 page,例如 pages/index/index
     */
    private String page;

    /**
     * 检查 page 是否存在,为 true 时 page 必须是已经发布的小程序存在的页面
     */
    private Boolean checkPath = Boolean.FALSE;

    /**
     * 要打开的小程序版本。正式版为 release,体验版为 trial,开发版为 develop
     */
    private String envVersion = "release";

    /**
     * 二维码的宽度,单位 px,最小 280px,最大 1280px
     */
    private Integer width;

    /**
     * 自动配置线条颜色
     */
    private Boolean autoColor = Boolean.FALSE;


    /**
     * 注册的用户角色
     */
    private Integer registerUserRole;

    /**
     * (平台业务员1)帮助注册的公司id
     */
    private Long registerCompanyId;


}

2.4 异常总结与解决(相对全面)

2.4.0 直接测试后发现问题

base64很短 访问后是这样的 如图所示
先看2.4.1(很重要) 不行在排查代码
在这里插入图片描述

2.4.1 (核心排查)使用微信官方接口测试查看问题

直接使用postman/apipost等 进行测试访问
如果返回的base64能在浏览器展示出来 则代码出现问题
反之 则您的 accessToken/path路径存在问题
curl(抓包数据)如下: 直接导入即可 修改accessToken和path

导入curl数据方法(如图所示)

在这里插入图片描述

curl: 抓包数据如下(导入即可)
curl --request POST \
  --url 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=77_TUdWM60vBoa3FofIKUQ8piUkH4Jd555A4Mknt19tKVyEPNUJ2bOyAHVGc_7iXiJs7ElXXjhs9IrOSD2JI1E5_Q3vWUXbRX0Z9YrDeLC9hEqSentISFSBRv9sbZgXMBjABAAP6' \
  --header 'content-type: application/json' \
  --data '{
    "width": 480,
    "auto_color": false,
    "page": "pages/index/index",
    "scene": "762350390017339392",
    "env_version": "trial"
}'

2.4.2 解决方案

场景: 用postman/apipost导入curl直接请求官方接口报错信息

异常一: (异常码41030)导入curl后, 报这个错误

则为: accessToken过期了 更换一个新的即可(如图所示)
文章传送门: => 微信小程序01: springboot获取accessToken方式
在这里插入图片描述

异常二: (异常码41030)无效的page参数(很坑)

特别注意: 这个page必须是正式版中存在的路径(pages/index/index是默认存在的)
其他路径需要上传并发布正式版后 并且验证路径真实存在后才可以使用
否则不可以生成二维码
如果默认的可以生成 其他路径均不可以生成 请联系前端打正式版并发布解决
在这里插入图片描述

异常三: (异常码40169)scene过长无法生成

微信文档中 不限制类型的scene有长度限制32位字符 超过则无法生成
在这里插入图片描述

异常N(跳过): 网络波动等访问超时/异常

换个网络试试, 代理关了等等(跳过)

2.4.3 正确结果(微信扫码测试一下)

其中 scene和env_version均可调整
在这里插入图片描述

2.4.4 接口请求测试

成功的参数复制到java接口参数json中进行代码测试
如果能正确展示base64 并且在网页中展示正常 则为成功(如图)
在这里插入图片描述

特殊: 如果只能显示出一半
  1. 调整width大小(一般没用)
  2. 调整base64方法
  3. 调整restTemplate方法

3. 文章的总结与预告

3.1 本文总结

  1. 使用00篇中的方法获取accessToken
  2. 获取不限制二维码
  3. 调整部分参数, 遇到问题 如 2.4中提到及解决方案
  4. base64转换
  5. restTemplate使用

3.2 下文预告

微信小程序04: 获取openId与unionId



@author: pingzhuyan
@description: ok
@year: 2024

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/600980.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

每日一题5:Pandas-修改列

一、每日一题 一家公司决定增加员工的薪水。 编写一个解决方案&#xff0c;将每个员工的薪水乘以2来 修改 salary 列。 返回结果格式如下示例所示。 解答&#xff1a; import pandas as pddef modifySalaryColumn(employees: pd.DataFrame) -> pd.DataFrame:employees.loc[…

C语言之数据结构之栈和队列的运用

目录 1. 用队列实现栈1.1 思路讲解1.2 代码实现 2. 用栈实现队列1.1 思路讲解1.2 代码实现 总结 •͈ᴗ•͈ 个人主页&#xff1a;御翮 •͈ᴗ•͈ 个人专栏&#xff1a;C语言数据结构 •͈ᴗ•͈ 欢迎大家关注和订阅!!! 1. 用队列实现栈 题目描述&#xff1a; 请你仅使用两个…

uniapp 自定义App UrlSchemes

需求&#xff1a;外部浏览器H5页面&#xff0c;跳转到uniapp开发的原生app内部。 1、uniapp内部的配置&#xff1a; &#xff08;1&#xff09;打开manifest->App常用其他设置&#xff0c;如下&#xff0c;按照提示输入您要设置的urlSchemes&#xff1a; &#xff08;2&am…

如何更好地使用Kafka? - 故障时解决

要确保Kafka在使用过程中的稳定性&#xff0c;需要从kafka在业务中的使用周期进行依次保障。主要可以分为&#xff1a;事先预防&#xff08;通过规范的使用、开发&#xff0c;预防问题产生&#xff09;、运行时监控&#xff08;保障集群稳定&#xff0c;出问题能及时发现&#…

自签名进行免杀

文章目录 什么是自签名使用cmd生成自签名文件对EXE进行签名将PFX签名使用脚本安装到受信任的根证书颁发机构 什么是自签名 在对抗AV/EDR中使用签名文件是一种很好的策略,拥有签名也就意味着是安全的程序, 大多数AV是不会杀签名程序的,但是签名程序的获取往往比较麻烦使用过期签…

RabbitMQ之消费者并发消费

为什么要引入消费者的并发消费&#xff1f; 当生产者的推送速度是远远超过消费者的能力的&#xff0c;可以提高消费者的消费速度。比如在java中我们可以启动多个 JVM 进程&#xff0c;实现多进程的并发消费&#xff0c;从而加速消费的速度&#xff0c;在mq中也可以通过设置配置…

Momentum靶机系列Momentum2

先进行arp扫描&#xff1a; 获得渗透靶机的IP&#xff1a;192.168.13.142 扫描一下靶机的使用的端口&#xff1a; 具有tcp端口和http服务的80端口 可以扫描一下80端口的http服务&#xff1a; 可以发现一个网站&#xff1a;http://192.168.13.142 打开该网址&#xff1a; 查看…

error code [1449]; The user specified as a definer (‘root‘@‘%‘) does not exist

其实就是说我的root用户权限不够&#xff0c;那就要加上权限&#xff0c;网上其他地方也有好多处理办法&#xff0c;但是要注意数据库版本。我用的是MySQL8.0.32版本&#xff0c;我是这样处理的&#xff0c;简单可行&#xff1a; GRANT ALL ON *.* TO root% ;FLUSH PRIVILEGES…

当AI遇见现实:数智化时代的人类社会新图景

文章目录 一、数智化时代的机遇二、数智化时代的挑战三、如何适应数智化时代《图解数据智能》内容简介作者简介精彩书评目录精彩书摘强化学习什么是强化学习强化学习与监督学习的区别强化学习与无监督学习的区别 前言/序言 随着科技的日新月异&#xff0c;我们步入了一个前所未…

爬虫学习:XPath匹配网页数据

目录 一、安装XPath 二、XPath的基础语法 1.选取节点 三、使用XPath匹配数据 1.浏览器审查元素 2.具体实例 四、总结 一、安装XPath 控制台输入指令&#xff1a;pip install lxml 二、XPath的基础语法 XPath是一种在XML文档中查找信息的语言&#xff0c;可以使用它在HTM…

B端系统菜单栏中使用阿里图标

B端系统菜单栏中使用阿里图标 1.需求说明 由于组件库自带的图标数量和内容有限&#xff0c;采用丰富多样的阿里图标是不错的选择 2.阿里图标使用 2.1官网 iconfont-阿里巴巴矢量图标库 2.2使用 2.2.1.先根据关键词搜索并选择对应的图标 注意&#xff1a;若只是少量的sv…

自动驾驶学习1-超声波雷达

1、简介 超声波雷达&#xff1a;利用超声波测算距离的雷达传感器装置&#xff0c;通过发射、接收 40kHz、48kHz或 58kHz 频率的超声波&#xff0c;根据时间差测算出障碍物距离&#xff0c;当距离过近时触发报警装置发出警报声以提醒司机。 超声波&#xff1a;人耳所不能听到的…

FMEA助力智能电网升级:构建安全、高效、可靠的电力网络

随着科技的不断进步&#xff0c;智能电网已成为现代电力行业的重要发展方向。而在这个过程中&#xff0c;FMEA&#xff08;失效模式和影响分析&#xff09;作为一种重要的质量管理工具&#xff0c;正日益发挥着其在智能电网建设中的赋能作用。本文将从FMEA的基本概念出发&#…

Study--Oracle-02-单实例部署Oracle19C

一、CentOS 7 环境准备 1、软件准备 操作系统&#xff1a;CentOS 7 数据库版本: Oracle19C 2、操作系统环境配置 关闭selinux &#xff0c;编辑 /etc/selinux/config文件&#xff0c;设置SELINUX enforcing 为SELINUXdisabled [rootoracle ~]# grep SELINUX /etc/seli…

顺序表的实现(迈入数据结构的大门)

什么是数据结构 数据结构是由&#xff1a;“数据”与“结构”两部分组成 数据与结构 数据&#xff1a;如我们所看见的广告、图片、视频等&#xff0c;常见的数值&#xff0c;教务系统里的&#xff08;姓名、性别、学号、学历等等&#xff09;&#xff1b; 结构&#xff1a;当…

python网络爬虫学习——编写一个网络爬虫

参考资料&#xff1a;用Python写网络爬虫&#xff08;第2版&#xff09; 1、编写一个函数 &#xff08;1&#xff09;用于下载网页&#xff0c;且当下载网页发生错误时能及时报错。 # 导入库 import urllib.request from urllib.error import URLError,HTTPError,ContentTooS…

Golang 开发实战day12 - Pointer

&#x1f3c6;个人专栏 &#x1f93a; leetcode &#x1f9d7; Leetcode Prime &#x1f3c7; Golang20天教程 &#x1f6b4;‍♂️ Java问题收集园地 &#x1f334; 成长感悟 欢迎大家观看&#xff0c;不执着于追求顶峰&#xff0c;只享受探索过程 Golang 开发实战day12 - 指针…

Hive读写文件机制

Hive读写文件机制 1.SerDe是什么&#xff1f; SerDe是Hive中的一个概念&#xff0c;代表着“序列化/反序列化” &#xff08;Serializer/Deserializer&#xff09;。 SerDe在Hive中是用来处理数据如何在Hive与底层存储系统&#xff08;例如HDFS&#xff09;之间进行转换的机制…

Xinstall广告效果监测,助力广告主优化投放策略

在移动互联网时代&#xff0c;APP推广已成为企业营销的重要手段。然而&#xff0c;如何衡量推广效果&#xff0c;了解用户来源&#xff0c;优化投放策略&#xff0c;一直是广告主和开发者面临的难题。这时&#xff0c;Xinstall作为国内专业的App全渠道统计服务商&#xff0c;以…

SpringBoot项目部署到阿里云服务器

部署步骤 步骤分以下&#xff1a; 将SpringBoot项目打包Linux上准备好Java环境、可用的MySql数据库项目上传到服务器启动项目停止项目 1.SpringBoot项目打包 数据库的链接&#xff0c;账户和密码需要和Linux上一致。 如上图打包即可。 2.Linux上准备好Java环境以及Mysql环境…