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
英文地址,請注明出處:http://en.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…