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

这篇具有很好参考价值的文章主要介绍了【微信小程序】微信小程序的接口调入 获取太阳码 根据返回值的类型进行接收,微信接口可能直接返回图片,也可能返回一个错误信息的json,同时兼容处理这两种情况。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

事件起因

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

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

环境和工具

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,结果读出来只有一部分,没有读取完,如下
在对这部分进行验证时:
【微信小程序】微信小程序的接口调入 获取太阳码 根据返回值的类型进行接收,微信接口可能直接返回图片,也可能返回一个错误信息的json,同时兼容处理这两种情况
inputstream的大小:
【微信小程序】微信小程序的接口调入 获取太阳码 根据返回值的类型进行接收,微信接口可能直接返回图片,也可能返回一个错误信息的json,同时兼容处理这两种情况
通过available方法获取到的大小只有8010,当前是win11系统
【微信小程序】微信小程序的接口调入 获取太阳码 根据返回值的类型进行接收,微信接口可能直接返回图片,也可能返回一个错误信息的json,同时兼容处理这两种情况
关于这个获取到的大小的问题,问了一下"万能"的chatgpt
【微信小程序】微信小程序的接口调入 获取太阳码 根据返回值的类型进行接收,微信接口可能直接返回图片,也可能返回一个错误信息的json,同时兼容处理这两种情况

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

结束语

若是对你有所帮助的话,希望能获得你的 点赞、评论、收藏,这将是对我很大的鼓励!!! 这对我真的很重要!!!
蟹蟹٩(‘ω’)و文章来源地址https://www.toymoban.com/news/detail-439388.html

到了这里,关于【微信小程序】微信小程序的接口调入 获取太阳码 根据返回值的类型进行接收,微信接口可能直接返回图片,也可能返回一个错误信息的json,同时兼容处理这两种情况的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【微信小程序】从网络请求返回值res.data获取并解析一个Array

    在微信小程序中,可以通过 res.data 获取到请求返回的数据。如果返回的数据是一个数组,您可以直接对其进行操作。 以下是一个示例代码,演示了如何从 res.data 中解析一个数组: 在上述代码中,我们首先判断 res.data 是否为一个数组,使用 Array.isArray() 方法进行判断。如果是

    2024年02月16日
    浏览(25)
  • 微信小程序获取接口数据与展现

    先来了解一下data的取值与赋值吧 data 是页面第一次渲染使用的初始数据。页面加载时,data 将会以JSON字符串的形式由逻辑层传至渲染层,因此data中的数据必须是可以转成JSON的类型:字符串,数字,布尔值,对象,数组。 { } 大括号,表示定义一个对象,大部分情况下要有成

    2024年02月09日
    浏览(48)
  • 微信小程序使用自定义tabbar 想要获取tabbar的高度,返回的结果是null,该如何获取?

    在使用自定义tabbar时,你可能会需要获取tabbar的高度,但是按照网上的方法却得不到正确的结果,这让你十分头疼。那么该怎么办呢?小编为大家整理了以下几个方法,希望能够帮到大家。 1️⃣ 使用wx.getSystemInfoSync()方法获取系统信息,然后通过计算得出tabbar的高度。 示例

    2024年02月11日
    浏览(47)
  • 微信小程序接口自动化-获取微信code

    https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 小程序登陆需要在小程序内部调用 wx.login() 的方法拿到 code,然后去请求服务获取到 token,后续的接口才能请求。 如何获取 code 去进行token获取。 Python 使用minium,JS 使用miniprogram-automator,这是微信官方提供的 UI 自动

    2024年02月08日
    浏览(33)
  • charles 如何获取电脑端微信小程序接口

    安装证书 设置代理端口 即可抓取美团酒店小程序的数据 从charles 可以抓取出header 请求,没有所谓的通过遍历循环能简单的得到数据,请求包含加密信息 随便改下数据就是 所以如果要得到这些数据,还非得通过小程序模拟人滑动获取数据,在企业数据开发中,也确实要重视

    2024年02月15日
    浏览(31)
  • 微信小程序接口调用凭证(获取token)auth.getAccessToken接口开发

    小程序接口调用凭证auth.getAccessToken接口规范参考链接 appid :小程序 appId secret :小程序 appSecret grant_type :授权类型,填写 client_credential access_token :获取到的凭证 expires_in :凭证有效时间,单位:秒。目前是7200秒之内的值。 errcode :错误码***(异常情况才会有错误码返回,

    2024年02月15日
    浏览(46)
  • 微信小程序获取手机号getPhoneNumber接口报错41001

    在使用 postman / apifox 调试微信小程序获取手机号接口时,微信报错 41001 : 该接口的请求报文其实是 表单参数 和 JSON参数 的集合体; 整个接口的请求需要 code 和 access_token 两个请求参数,接口的URL里边包含了 access_token : 但是没有包含 code ,也就意味着 access_token 是需要作为

    2024年02月11日
    浏览(30)
  • 微信小程序——获取接口调用凭据access_token

    今天在搞一个微信小程序的时候,使用到了发布内容的问题,然后想使用微信请求接口,结果遇到了请求接口需要获取调用凭证access_token。 打开微信小程序开发文档后,打开服务端相关文档,如下图: 图中可以看到功能的描述,他是获取全局唯一后台接口调用凭证,有效期

    2024年01月16日
    浏览(44)
  • 【微信小程序】使用和风天气接口api(全过程)——获取天气

    介绍 这里是小编成长之路的历程,也是小编的学习之路。希望和各位大佬们一起成长! 以下为小编最喜欢的两句话: 要有最朴素的生活和最遥远的梦想,即使明天天寒地冻,山高水远,路远马亡。 一个人为什么要努力? 我见过最好的答案就是:因为我喜欢的东西都很贵,

    2023年04月08日
    浏览(57)
  • 微信小程序如何使用地球半径计算两组经纬度点之间的距离(自身位置与接口返回位置)【上】

    目录 1.配置位置权限  2.获取当前自身经纬度  3. 请求接口拿到返回经纬 4. 循环取每一项的经纬 5.如何判断是否打开了定位权限  6.进行距离计算操作  7.运行效果 8.完整代码 首先在使用小程序时,请求的接口一定要去配置合法域名,才能够进行接下来的操作。  在app.json中添

    2024年02月06日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包