【微信小程序】微信小程序的接口调入 获取太阳码 根据返回值的类型进行接收,微信接口可能直接返回图片,也可能返回一个错误信息的json,同时兼容处理这两种情况

news2024/12/27 10:52:33

目录

    • 事件起因
    • 环境和工具
    • 操作过程
    • 解决办法
    • 遇到的一点问题
    • 结束语

事件起因

在开发一个关于微信小程序的过程中,有一个这样的需求,要求生成微信小程序的太阳码,然而这个东西的请求方式我们是这样的:我作为后端服务去请求这个太阳码的二维码,然后将获取到的太阳码二维码的图片返回给小程序端进行接收,然后小程序端进行一个展示

原本以为他们小程序端直接去请求那个图片就行了,但是最后商讨下来还是由我们后端去请求这个太阳码,然后返回给前端去展示
过程中就遇到一些数据请求和转换的问题,就先在这儿记录一下,以便后来者踩坑

环境和工具

java jdk1.8

操作过程

先是接口层,最后完成的版本是这样:

    @PostMapping("/getSunQRCode")
    @ApiOperation(value = "生成太阳码-获取小程序不限制的QR码", notes = "生成太阳码-获取小程序不限制的QR码")
    public Result<SunQRCodeVo> getUnlimitedQRCode(@RequestBody UnlimitedQRCodeDTO unlimitedQRCodeDTO, HttpServletResponse response) throws IOException {
        return newUserService.getUnlimitedQRCode(unlimitedQRCodeDTO);
    }

大致解释j就是一个post请求,然后这个请求返回的是一个封装后的实体的Result,然后内部的实体是一个字符串(之所以是字符串,是因为最后图片以base64编码的格式返回给前端的,不然就得以流的形式返回

然后就是具体的实现层的操作,大致操作如下:

通过微信的接口请求太阳码 ----》将拿到的太阳码转换为对应的图片格式(微信那边默认返回的是jpeg格式,因为前端的要求,需要转换为png的格式,然后再转换为对应的base64的字符串,然后再返回给前端) ----》转换为base64的格式,封装实体返回给前端。

解决办法

最后的一个实现层的代码版本(这个代码有个优势:就是可以根据微信接口的返回内容,如果请求正确,微信的这个接口它会直接返回buffer的图片,但如果请求有问题,它的返回内容又是一个json,所以这种情况可以根据返回的内容去判断,然后再具体去考虑如何接收

import org.springframework.web.client.RestTemplate;

@Service("NewUserService")
public class NewUserServiceImpl extends BaseServiceImpl<NewUserDao, NewUserDO, BaseDTO> implements NewUserService {

private static RestTemplate restTemplate;

    public static RestTemplate getRestTemplate() {
        if (null == restTemplate) {
            synchronized (RestTemplate.class) {
                if (null == restTemplate) {
                    restTemplate = new RestTemplate();
                }
            }
        }
        return restTemplate;
    }


/**
     * 获取微信小程序的小程序码
     */
    @Override
    public Result<SunQRCodeVo> getUnlimitedQRCode(UnlimitedQRCodeDTO unlimitedQRCodeDTO) throws IOException {
        Result<SunQRCodeVo> result = new Result<>();
        //先根据配置的appid等信息获取到token
        String accessToken = this.getAccessToken().getAccess_token();

        String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken;

//        byte[] qrCodeVo = getRestTemplate().postForObject(url, paramMap, byte[].class,
//                ContentType.APPLICATION_JSON);
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost request = new HttpPost(url);
        request.setHeader("Content-Type", "application/json");

        // 将json参数作为请求体发送
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("scene",unlimitedQRCodeDTO.getScene());
        jsonParam.put("env_version",unlimitedQRCodeDTO.getEnv_version());
        jsonParam.put("page",unlimitedQRCodeDTO.getPage());
        jsonParam.put("width",unlimitedQRCodeDTO.getWidth()==null?"280":unlimitedQRCodeDTO.getWidth());

        StringEntity entity = new StringEntity(jsonParam.toString(), ContentType.APPLICATION_JSON);
        request.setEntity(entity);

        CloseableHttpResponse response = client.execute(request);

        // 获取响应头中的Content-Type字段
        Header contentTypeHeader = response.getFirstHeader("Content-Type");
        if (contentTypeHeader != null && contentTypeHeader.getValue().contains("image/jpeg")) {

            // 如果返回值是jpeg类型,以输入流的形式读取
            InputStream is = response.getEntity().getContent();

            //字节数组的输出流,用户辅助图片在流之间的格式转换
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

            //将请求获取到的输入流 使用ImageIO转换为bufferedImage后以png的格式写入输出流,然后将输出流转换为字节数组,后面将字节数组转换为base64编码的字符串
            BufferedImage image = ImageIO.read(is);
            ImageIO.write(image, "png", outputStream);
            byte[] pngBytes = outputStream.toByteArray();
            outputStream.close();


            /* 该段注释代码 作用是
            byte[] buffer = new byte[1024];
            int length;
            while ((length = is.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
            }
            byte[] data = outputStream.toByteArray();
            */
            //关闭创建的输入流inputStream
            is.close();
            SunQRCodeVo sunQRCodeVo = new SunQRCodeVo();
//            sunQRCodeVo.setData(data);
            // 二进制数据字节数组 转base64编码的字符串
            sunQRCodeVo.setBase64buffer(Base64.getEncoder().encodeToString(pngBytes));
            sunQRCodeVo.setErrcode(0);
            result.setResult(sunQRCodeVo);
            return result;
        } else {
            // 如果返回值是json类型,则解析json数据
            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            String line;
            StringBuilder sb = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();
            String json = sb.toString();
            JSONObject obj = new JSONObject(json);
            SunQRCodeVo sunQRCodeVo = new SunQRCodeVo();
            sunQRCodeVo.setErrcode(obj.getInt("errcode"));
            sunQRCodeVo.setErrmsg(obj.getString("errmsg"));
            return result.error500(obj.getString("errmsg"));
        }
    }
    //访问微信的服务器找到指定的小程序,获取登录
    public AccessTokenVo getAccessToken() {
        String url =
                "https://api.weixin.qq.com/cgi-bin/token?grant_type=" + GRANT_TYPE + "&appid=" + APPID + "&secret=" + SECRET;
        return getRestTemplate().getForObject(url, AccessTokenVo.class);
    }

}

原本只贴了一个实现的方法,后面发现可能那个RestTemplate可能看不懂,就又给这个方法的import的包和在该实现层的具体实现给附加上了,上面代码中还有几个实体结构也在下面:

用于获取AccessTokenVo 的实体类:

@Data
public class AccessTokenVo {

    private String access_token;

    private Integer expires_in;

    /**
     * @description:
     * -1.系统繁忙,此时请开发者稍候再试
     * 0.请求成功
     * 40001.AppSecret 错误或者 AppSecret 不属于这个小程序,请开发者确认 AppSecret 的正确性
     * 40002.请确保 grant_type 字段值为 client_credential
     * 40013.不合法的 AppID,请开发者检查 AppID 的正确性,避免异常字符,注意大小写
     * @param: @param null
     * @return:
     * @author: liuanmin
     * @date: 2022/4/29
     */
    private Integer errcode;

    private String errmsg;
}

用于疯转返回请求的SunQRCode实体:

@Data
public class SunQRCodeVo {
    /**
     * 二进制流
     */
    private byte[] data;

    /**
     * 图片二进制流转base64编码的字符串
     */
    private String base64buffer;

    /**
     * 小程序返回的错误码
     */
    private Integer errcode;

    /**
     * 小程序返回的错误信息
     */
    private String errmsg;
}

遇到的一点问题

上面有一小段我注释里的代码,是之前遇到的一点问题,但是经过排查后发现的问题所在如下:

拿到请求的内容后我使用new一个字节数组的大小刚好与返回获取的流一样的大小去读取这个InputStream,结果读出来只有一部分,没有读取完,如下
在对这部分进行验证时:
在这里插入图片描述
inputstream的大小:
在这里插入图片描述
通过available方法获取到的大小只有8010,当前是win11系统
在这里插入图片描述
关于这个获取到的大小的问题,问了一下"万能"的chatgpt
在这里插入图片描述

顺便说一下,这段时间以来使用chatgpt的一个感受:
能用,确实也挺智能,在数据库的管理和代码的提示上能提供不小的帮助,但也有一些小毛病,比如说 突然崩了,有时候对话它逻辑跟不上,有时候反应慢,有时候不能根据前面指定内容进行继续回答,还有就是回答内容过长时会断,让它继续输出时,中间会缺失部分内容;还有部分问题太细太专业,它也回答不了。
你描述得越准确,它的回答就越符合你的期望,将你的背景,使用情况描述得越清楚,就越贴近你想要的结果。

结束语

若是对你有所帮助的话,希望能获得你的 点赞、评论、收藏,这将是对我很大的鼓励!!! 这对我真的很重要!!!
蟹蟹٩(‘ω’)و

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MFAC】基于紧格式动态线性化的无模型自适应控制(Matlab代码)

例题来源&#xff1a;侯忠生教授的《无模型自适应控制&#xff1a;理论与应用》&#xff08;2013年科学出版社&#xff09;。 &#x1f449;对应书本 4.2 单输入单输出系统(SISO)紧格式动态线性化(CFDL)的无模型自适应控制(MFAC) 例题4.1 题目要求 matlab代码 clc; clear al…

ASEMI代理ADXL345BCCZ-RL7原装ADI车规级ADXL345BCCZ-RL7

编辑&#xff1a;ll ASEMI代理ADXL345BCCZ-RL7原装ADI车规级ADXL345BCCZ-RL7 型号&#xff1a;ADXL345BCCZ-RL7 品牌&#xff1a;ADI /亚德诺 封装&#xff1a;LGA-14 批号&#xff1a;2023 安装类型&#xff1a;表面贴装型 引脚数量&#xff1a;14 工作温度:-55C~105C…

HTTPS连接建立过程

目录 前言什么是HTTPSHTTPS的作用 TLS建立连接过程1、TCP三次握手2、Client Hello3、Sever Hello4、校验数字证书5、客户端回应6、服务器回应7、TCP四次挥手 前言 什么是HTTPS HTTPS&#xff0c;Hyper Text Transfer Protocol over SecureSocket Layer&#xff0c;超文本传输…

「自动化」聊起来简单,做起来难 | 谈效风生

第4期&#xff1a;“自动化”聊起来简单&#xff0c;做起来难 在上一期《如何找到现有研发体系的「内耗问题」?》中&#xff0c;我们聊了评估现有研发体系&#xff0c;正确的找到“体系内耗问题”&#xff0c;是改变研发体系的第一步。本期我们继续聊下一个关键点就是研发体系…

MIT6.824 lab4B实验记录

Background 主要是完成一个可以根据group数量&#xff0c;动态调整shard所属的group的分布式kv键值引擎。其中shard->group的配置由shardctrler集群来管理&#xff0c;底层也是通过raft group来容错&#xff08;分布式嘛&#xff09; 然后这个shardkv就是要完成的是根据sh…

哪些地方能发表计算机论文? - 易智编译EaseEditing

计算机科学领域是一个快速发展的领域&#xff0c;每年都会涌现出许多新的科技和新的研究成果。 为了保证研究成果的质量和可信度&#xff0c;科学家们通常会通过期刊来发表自己的研究成果。 SCI期刊是世界著名的科技期刊数据库&#xff0c;被认为是科技领域内的权威数据库之一…

docker 系列之 Dockerfile 文件里 cmd命令与entrypoint命令区别

文章目录 一、cmd&#xff1a;用法1&#xff1a;带有中括号的形式用法2&#xff1a;shell form&#xff0c;即没有中括号的形式 二、entrypoint&#xff1a;第一种&#xff1a;命令行模式&#xff0c;也就是带中括号第二种&#xff1a;shell模式 三、总结&#xff1a; 一、cmd&…

《人月神话》纪念典藏版撤下了以前的宣传语

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>> 《人月神话》作者Frederick Phillips Brooks Jr. 于2022年11月17日逝世。 清华大学出版社近期将发行《人月神话》纪念典藏版。 新版的封底如下&#xff0c;宣传语更换成了…

CleanMyMac X4.13.2.dmg最新中文版下载

它是Mac上一款美观易用的系统优化清理工具&#xff0c;也是小编刚开始用Mac时的装机必备。它能够清理系统垃圾&#xff0c;提升电脑的运行速度&#xff0c;卸载许久不用的软件&#xff0c;使其变得如新机一般流畅。 CleanMyMac X是一款专业的Mac清理软件&#xff0c;可智能清理…

al智能改写工具-ai自动生成文章软件

随着互联网的发展&#xff0c;文章编辑在不断地向自动化、高效化方向进行转变&#xff0c;一款名叫“改稿神器”的工具应运而生。它可以帮助我们快速实现全自动批量改稿&#xff0c;做到没有错别字&#xff0c;自动优化语法&#xff0c;自动插入图片&#xff0c;严格按照标准的…

【腾讯云FinOps Crane 集训营】初识 FinOps Crane

前言&#xff1a; 有幸参加了腾讯云Finops Crane 集训营&#xff0c;学到了很多东西&#xff0c;现在将内容分享给大家。 Finops Crane &#xff1a;是一个基于 FinOps 的云资源分析与成本优化平台。 它的目标是希望在保证客户应用运行质量的前提下&#xff0c;实现极致的降本。…

web前端面试题汇总大全 -- 持续更新!

文章目录 一、html 系列 ⭐⭐⭐⭐⭐1、H5新增特性和css3新增特性&#xff1f; 二、css 系列 ⭐⭐⭐⭐⭐1、BFC的理解&#xff1f;2、说说你对盒模型的理解&#xff1f;3、如何实现元素⽔平垂直居中&#xff1f;4、CSS如何画⼀个三⻆形&#xff1f;原理是什么&#xff1f;5、说说…

二分查找基础篇-JAVA

文章目录 前言 大家好,我是最爱吃兽奶,这篇博客给大家介绍一下二分查找,我们先从最基本的开始讲解,再慢慢深入,把优化和变形也和大家说一下,那么,跟着我的步伐,我们一起去看看吧! 一、什么是二分查找? 二分查找(Binary Search)也称作折半查找 二分查找的效率很高,每查找一次…

Adam优化器及其变种的原理

本文将从SGD开始介绍Adam优化器的原理以及其变种的提出背景。 1、SGD的原理 SGD&#xff08;随机梯度下降法&#xff09;是基于最速梯度下降法的原理&#xff0c;假设我们存在损失函数&#xff0c;其中是要学习参数&#xff0c;定义如下的优化路径&#xff0c;使得损失函数值最…

Ray使用案例

Ray Use Cases Ray用例 本页索引了用于扩展ML的常见Ray用例。它包含了对博客、例子和教程的突出引用,也位于Ray文档的其他地方。 大型语言模型和生成型人工智能 大型语言模型(LLMs)和生成性人工智能正在迅速改变行业,并以惊人的速度要求计算。Ray为这些模型的扩展提供了…

我让ChatGPT用CSS3画一个皮卡丘,还是自己画的可爱

突然想到了小时候看过的动画片《皮卡丘》&#xff0c;于是突然就想&#xff0c;ChatGPT肯定也看过&#xff0c;他哪有不知道的东西啊&#xff0c;于是就想着让他帮我画一个&#xff0c;他画出来之后&#xff0c;我笑了&#xff0c;这啥玩意儿啊。 目录 一、第一次尝试让ChatGP…

智安网络|怎么预防大大小小的网络入侵及信息泄露?五招值得收藏

网络安全是一个涵盖广泛、变幻多端的领域。网络风险防范需要多种措施&#xff0c;从教育人员如何正确处理机密信息到定期检查系统的安全性。 在现代网络环境下&#xff0c;网络安全成为防护重点&#xff0c;网络环境下出现的安全隐患可能会直接影响业务&#xff0c;甚至生命财…

【fiddler+burp+雷神模拟器联动抓包】

0x00 常用抓包工具 常用的抓包工具​有fiddler、wireshark、httpwatch、 firebug、F12/等。抓包抓的是协议&#xff0c;fiddler抓的是HTTP、HTTPS协议&#xff0c;wireshark抓的是其他协议。fiddler、wireshark可以修改接口的参数和返回值&#xff0c;常用的F12调试工具只可以…

npm 知识点

1 ~会匹配最近的小版本依赖包&#xff0c;比如~1.1.3会匹配所有1.1.x版本&#xff0c;但是不包括1.2.0 ^会匹配最新的大版本依赖包&#xff0c;比如^1.3.4会匹配所有1.x.x的包&#xff0c;包括1.3.4&#xff0c;但是不包括2.0.0 *会匹配最新版本 2 ant-design/pro-table 前面…

EndNote X9 引用参考 单击文献编号,不能跳转到文尾文献列表处,咋解决?文献编号 不能跳转 ,怎么办?

文章目录 1 正常情况下 引用文献编号 是可以跳转的2 问题分析3 解决方法4 EndNote X9 插入参考文献常见问题总结5 EndNote X9 快速上手教程&#xff08;毕业论文参考文献管理器&#xff09; 1 正常情况下 引用文献编号 是可以跳转的 正确的插入文献后&#xff0c; 正常情况下&a…