Java 生成微信小程序二维码

1. java 二维码生成工具类


import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.pdatao.api.controller.file.FileController;
import com.pdatao.api.error.CommunityException;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;@Component
public class MpQrCodeUtil {@ResourceFileController fileController;@Value("${mp.wechat.appid}")private String mpAppId;@Value("${mp.wechat.secret}")private String mpSecretId;@Value("${qrcode.pageHome}")private String pageHome;@Value("${spring.profiles.active:}")private String activeProfile;private static final String API_GET_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";private static final String API_GET_QR_CODE = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";private static String cachedToken = null;private static long tokenExpireTime = 0;public String getMpQRCode(Long orderId, HttpServletRequest request) throws Exception {String scenes = "id=" + orderId + "&v=1";String envVersion = "";if ("prod-plus".equals(activeProfile)) {envVersion = "release";}return this.getQRCodeWeb(scenes,envVersion,orderId,request);}public String getQRCodeWeb(String scenes, String envVersion, Long orderId, HttpServletRequest request) throws Exception {String accessToken = getToken(mpAppId, mpSecretId);return getQRCode(accessToken, scenes, envVersion, orderId, request);}public static String getToken(String appId, String appSecret) throws Exception {// 1. 检查缓存是否有效if (cachedToken != null && System.currentTimeMillis() < tokenExpireTime) {return cachedToken;}HttpURLConnection conn = null;try {String url = String.format(API_GET_TOKEN, appId, appSecret);conn = (HttpURLConnection) new URL(url).openConnection();conn.setConnectTimeout(5000);conn.setReadTimeout(5000);conn.setRequestMethod("GET");int statusCode = conn.getResponseCode();if (statusCode != 200) {// 读取错误流String errorJson = IOUtils.toString(conn.getErrorStream(), StandardCharsets.UTF_8);throw new CommunityException("微信接口错误: " + errorJson);}JSONObject result = new JSONObject(IOUtils.toString(conn.getInputStream(), StandardCharsets.UTF_8));cachedToken = result.getStr("access_token");long expiresIn = result.getLong("expires_in") * 1000; // 转为毫秒tokenExpireTime = System.currentTimeMillis() + expiresIn - 600_000;return cachedToken;} finally {if (conn != null) conn.disconnect();}}public String getQRCode(String accessToken, String scenes, String envVersion, Long orderId, HttpServletRequest request) throws Exception {HttpURLConnection httpURLConnection = null;try {URL url = new URL(String.format(API_GET_QR_CODE, accessToken));httpURLConnection = (HttpURLConnection) url.openConnection();httpURLConnection.setRequestMethod("POST");// 提交模式// 发送POST请求必须设置如下两行httpURLConnection.setDoOutput(true);httpURLConnection.setDoInput(true);// 发送请求参数com.alibaba.fastjson.JSONObject paramJson = new com.alibaba.fastjson.JSONObject();paramJson.put("scene", scenes);paramJson.put("page", pageHome);paramJson.put("env_version", StrUtil.isNotEmpty(envVersion) ? envVersion : "trial");paramJson.put("check_path", false);try (PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream())) {printWriter.write(paramJson.toString());printWriter.flush();}// 检查响应码int responseCode = httpURLConnection.getResponseCode();if (responseCode != HttpURLConnection.HTTP_OK) {cachedToken = null;throw new CommunityException("生成二维码失败:HTTP错误码 " + responseCode);}// 检查内容类型String contentType = httpURLConnection.getContentType();if (contentType == null || !contentType.startsWith("image/")) {cachedToken = null;throw new CommunityException("生成二维码失败:接口返回非图片数据(" +  (contentType != null ? contentType : "未知内容类型") + ")");}try (InputStream is = httpURLConnection.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();) {byte[] buffer = new byte[1024];int len = -1;while ((len = is.read(buffer)) != -1) {baos.write(buffer, 0, len);}byte[] imageData = baos.toByteArray();// 简单验证是否是有效图片(可选)if (imageData.length == 0) {cachedToken = null;throw new CommunityException("生成二维码失败:返回空图片数据");}MultipartFile multipartFile = new ByteArrayMultipartFile(orderId + "_mpqrcode",          // 表单字段名orderId + "_mpqrcode.png",      // 文件名"image/png",                  // 内容类型imageData                  // 内容);com.alibaba.fastjson.JSONObject json = fileController.upload(multipartFile,request);if (json == null || !json.containsKey("url")) {throw new CommunityException("上传图片失败:响应数据异常");}return json.getString("url");}} catch (Exception e) {e.printStackTrace();throw new CommunityException("生成二维码失败:"+e.getMessage());} finally {if (httpURLConnection != null) {httpURLConnection.disconnect();}}}}

2. 部分可自行调整的代码解释

FileController: 我自己的上传图片到服务器的类

mpAppId:  小程序appid

mpSecretId: 小程序 SecretId

pageHome: 要跳转的小程序的页面地址(例如: ‘pages/userInfo/userInfoHome’)

activeProfile: 我自己的判断当前运行环境的配置(可以忽略)

@Resource
FileController fileController;@Value("${mp.wechat.appid}")
private String mpAppId;
@Value("${mp.wechat.secret}")
private String mpSecretId;@Value("${qrcode.pageHome}")
private String pageHome;
@Value("${spring.profiles.active:}")
private String activeProfile;

getMpQRCode 外部调用的方法,自定义自己需要传入什么值

Long orderId : 这个是我为了生成二维码路径时携带的参数

HttpServletRequest request: 这个参数,和二维码生成逻辑没有任何关系,我这里使用只是因为上传图片的地方需要这个值,这个比较冗余

scenes: 定义页面地址携带什么参数

if ("prod-plus".equals(activeProfile)) {envVersion = "release";
}      这个是为了判断生成什么环境的二维码图片(正式版/ 体验版) 
public String getMpQRCode(Long orderId, HttpServletRequest request) throws Exception {String scenes = "id=" + orderId + "&v=1";String envVersion = "";if ("prod-plus".equals(activeProfile)) {envVersion = "release";}return this.getQRCodeWeb(scenes,envVersion,orderId,request);
}

imageData : 这个就是生成的二维码图片信息

下面的其他信息,都是为了把这个图片的信息,上传到自己项目中保存,最终返回图片地址

byte[] imageData = baos.toByteArray();// 简单验证是否是有效图片(可选)
if (imageData.length == 0) {throw new CommunityException("生成核销二维码失败:返回空图片数据");
}MultipartFile multipartFile = new ByteArrayMultipartFile(orderId + "_mpqrcode",          // 表单字段名orderId + "_mpqrcode.png",      // 文件名"image/png",                  // 内容类型imageData                  // 内容
);
com.alibaba.fastjson.JSONObject json = fileController.upload(multipartFile,request);
if (json == null || !json.containsKey("url")) {throw new CommunityException("上传二维码失败:响应数据异常");
}
return json.getString("url");

3.小程序中获取携带的参数

以我上述的参数为例:(微信小程序使用的 uniapp)

onLoad(option) {if (option.scene) {const scene = decodeURIComponent(option.scene);const params = this.parseSceneParams(scene);console.log(params.id)console.log(params.v)}},methods: {parseSceneParams(scene) {const params = {};if (!scene) return params;const pairs = scene.split('&');pairs.forEach(pair => {const [key, value] = pair.split('=');if (key) params[key] = value;});return params;},
}

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

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

相关文章

智慧健康触手可及:AI健康小屋——未来健康管理的全能守护者

AI健康小屋&#xff0c;这座融合人工智能、物联网与医疗科技的“健康堡垒”&#xff0c;正悄然重构健康管理生态。它以科技为引擎&#xff0c;将专业医疗资源下沉至社区、企业、家庭&#xff0c;通过智能检测、精准分析、个性化干预&#xff0c;实现从疾病治疗到主动预防的健康…

[工作表控件19] 验证规则实战:如何用正则表达式规范业务输入?

在企业应用中,数据准确性至关重要。工作表控件通过“验证规则”能力,支持在文本字段和附件字段中使用正则表达式(RegEx)进行格式校验。它能帮助开发者轻松实现邮箱、身份证号、车牌号、URL 等格式的高效验证,大幅提升数据质量与表单使用体验。 一、官方功能介绍与基础能力…

uniapp分包实现

关于分包优化的说明 在对应平台的配置下添加"optimization":{"subPackages":true}开启分包优化 目前只支持mp-weixin、mp-qq、mp-baidu、mp-toutiao、mp-kuaishou的分包优化 分包优化具体逻辑&#xff1a; 静态文件&#xff1a;分包下支持 static 等静态…

ctfshow_web14------(PHP+switch case 穿透+SQL注入+文件读取)

题目&#xff1a;解释&#xff1a;$c intval($_GET[c]); //获取整数值 6sleep($c);//延迟执行当前脚本若干秒。提示一下哈没有break会接着执行下面的但是像是44444&#xff0c;555555,sleep的时间太久我们用3进入here_1s_your_f1ag.php是一个查询页面&#xff0c;sql注入查看源…

linux x86_64中打包qt

下载安装 地址: Releases linuxdeploy/linuxdeploy mv linuxdeploy-x86_64.AppImage linuxdeployqtchmod 777 linuxdeployqtsudo mv linuxdeployqt /usr/local/bin/linuxdeployqt --version报错 Applmage默认依赖FUSE&#xff0c;需要挂载自身为虚拟文件系统才能运行, ubuntu…

华为昇腾CANN开发实战:算子自定义与模型压缩技术指南

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;注册即送-H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 摘要 随着人工智能技术的飞速发展&#xff0c;越来越多…

Vue3源码reactivity响应式篇之reactive响应式对象的track与trigger

概览 在BaseReactiveHandler类的get方法中&#xff0c;有如下代码块if (!isReadonly2){track(target, "get", key);}&#xff0c;这表示通过reactive、shallowReactive创建的响应式对象&#xff0c;非只读的&#xff0c;当读取代理对象proxyTarget的某个属性key时&am…

VRRP 多节点工作原理

VRRP 多节点工作原理 基本概念 VRRP 的设计初衷是给一组节点提供一个 虚拟路由器&#xff0c;对外只表现出一个 VIP。协议规定&#xff1a;同一个 VRRP 实例 下始终只有 一个 Master 持有 VIP&#xff0c;其它全部是 Backup。 Master → 持有 VIP&#xff0c;负责转发流量到Mas…

Gradio全解11——Streaming:流式传输的视频应用(9)——使用FastRTC+Gemini创建沉浸式音频+视频的艺术评论家

Gradio全解11——Streaming&#xff1a;流式传输的视频应用&#xff08;9&#xff09;——使用FastRTCGemini创建沉浸式音频视频的艺术评论家11.9 使用FastRTCGemini创建实时沉浸式音频视频的艺术评论家11.9.1 准备工作及音频图像编码器1. 项目说明及准备工作2. 音频和图像编码…

Django入门笔记

Python知识点&#xff1a;函数、面向对象。前端开发&#xff1a;HTML、CSS、JavaScript、jQuery、BootStrap。MySQL数据库。Python的Web框架&#xff1a;Flask&#xff0c;自身短小精悍 第三方组件。Django&#xff0c;内部已集成了很多组件 第三方组件。【主要】1.安装djang…

当Claude Code失灵,Qwen Code能否成为你的救星?

当Claude Code失灵&#xff0c;Qwen Code能否成为你的救星&#xff1f; 一、开头&#xff1a;点明困境&#xff0c;引出主角 作为一个大模型博主&#xff0c;日常工作中我经常会使用各种 AI 工具来提高效率&#xff0c;Claude Code 就是我之前非常依赖的一款代码生成助手 。它…

Go语言快速入门教程(JAVA转go)——1 概述

优势 第一个理由&#xff1a;对初学者足够友善&#xff0c;能够快速上手。 业界都公认&#xff1a;Go 是一种非常简单的语言。Go 的设计者们在发布 Go 1.0 版本和兼容性规范后&#xff0c;似乎就把主要精力放在精心打磨 Go 的实现、改进语言周边工具链&#xff0c;还有提升 Go …

【Rust多进程】征服CPU的艺术:Rust多进程实战指南

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

OpenCV 高阶实战:图像直方图与掩码图像深度解析

目录 一、图像直方图&#xff1a;读懂图像的 “像素分布报告” 1. 什么是图像直方图&#xff1f; 2. 图像直方图的核心作用 &#xff08;1&#xff09;分析亮度分布 &#xff08;2&#xff09;判断对比度高低 &#xff08;3&#xff09;辅助图像增强与阈值分割 &#xf…

基于stm32的家庭安全监测系统设计

若该文为原创文章&#xff0c;转载请注明原文出处。一、引言&#xff08;一&#xff09;研究背景及意义背景&#xff1a;随着智能家居概念的普及&#xff0c;人们对家庭安全、舒适度和节能提出了更高要求。传统安防系统功能单一、各系统独立&#xff0c;缺乏联动和远程管理能力…

Oracle体系结构-控制文件(Control Files)

一、 原理 (Principle) 核心定位&#xff1a; 控制文件是一个小型的二进制文件&#xff0c;由 Oracle 实例在启动和操作过程中持续读写。它是数据库物理结构的权威记录。数据库无法启动或正常操作时&#xff0c;如果无法访问控制文件&#xff0c;实例将无法识别数据文件和重做日…

路由 下一跳 网关 两个不同网段的ip如何通过路由器互通

路由 (Routing)核心思想&#xff1a;路径选择是什么&#xff1f; 路由是指数据包从源主机传输到目标主机的整个过程。这个过程就像寄快递&#xff1a;你需要决定包裹经过哪些中转站才能最终到达收件人手里。做什么&#xff1f; 网络中的设备&#xff08;主要是路由器&#xff0…

HiDDeN论文解读与代码实现

论文&#xff1a;HiDDeN: Hiding Data With Deep Networks 作者&#xff1a;Jiren Zhu, Russell Kaplan, Justin Johnson, Li Fei-Fei一、研究背景 在图像信息隐藏领域&#xff0c;通常有两类典型的应用场景&#xff1a;隐写 (Steganography) 目标&#xff1a;实现秘密通信。要…

实验室服务器配置|实验室多人共享GPU|通过Docker实现Linux系统多用户隔离与安全防控

利用实验室服务器跑实验的时候&#xff0c;通常就是两种方案&#xff0c;一个是向日葵远程桌面进行操作&#xff0c;一个是通过ssh进行连接&#xff0c;用ssh的话&#xff0c;一般服务器都在内网&#xff08;例如校园网&#xff09;&#xff0c;是无法在公网&#xff08;不在校…

2019考研数学(二)真题

一、选择题 (1) (2) (3) (4) 遗漏点&#xff1a;由通解知特解&#xff0c;特解代入微分方程 (5) ★记住这个题&#xff0c;用的泰勒展开(6) (7) 遗忘点&#xff1a; ★伴随矩阵的秩与原矩阵秩的关系&#xff1a; (8) 错误点&#xff1a;粗心 二、填空题 (9) 易混淆点&#xff…