最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java生成微信小程序二維碼完整實(shí)例代碼

 更新時(shí)間:2025年09月11日 10:48:51   作者:.也許.  
微信小程序是一種輕量級(jí)的應(yīng)用程序,用戶無需下載安裝即可使用,因此受到了廣泛的歡迎,這篇文章主要介紹了Java生成微信小程序二維碼的相關(guān)資料,包含上傳圖片、參數(shù)傳遞及二維碼生成邏輯,詳細(xì)說明了各組件作用及使用方法,需要的朋友可以參考下

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 {

    @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;

    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) {
                // 讀取錯(cuò)誤流
                String errorJson = IOUtils.toString(conn.getErrorStream(), StandardCharsets.UTF_8);
                throw new CommunityException("微信接口錯(cuò)誤: " + errorJson);
            }


            JSONObject result = new JSONObject(IOUtils.toString(conn.getInputStream(), StandardCharsets.UTF_8));

            cachedToken = result.getStr("access_token");
            long expiresIn = result.getLong("expires_in") * 1000; // 轉(zhuǎn)為毫秒
            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");// 提交模式
            // 發(fā)送POST請求必須設(shè)置如下兩行
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);

            // 發(fā)送請求參數(shù)
            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();
            }

            // 檢查響應(yīng)碼
            int responseCode = httpURLConnection.getResponseCode();
            if (responseCode != HttpURLConnection.HTTP_OK) {
                cachedToken = null;
                throw new CommunityException("生成二維碼失?。篐TTP錯(cuò)誤碼 " + responseCode);
            }

            // 檢查內(nèi)容類型
            String contentType = httpURLConnection.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                cachedToken = null;
                throw new CommunityException("生成二維碼失?。航涌诜祷胤菆D片數(shù)據(jù)(" +  (contentType != null ? contentType : "未知內(nèi)容類型") + ")");
            }

            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();

                // 簡單驗(yàn)證是否是有效圖片(可選)
                if (imageData.length == 0) {
                    cachedToken = null;
                    throw new CommunityException("生成二維碼失敗:返回空圖片數(shù)據(jù)");
                }

                MultipartFile multipartFile = new ByteArrayMultipartFile(
                        orderId + "_mpqrcode",          // 表單字段名
                        orderId + "_mpqrcode.png",      // 文件名
                        "image/png",                  // 內(nèi)容類型
                        imageData                  // 內(nèi)容
                );
                com.alibaba.fastjson.JSONObject json = fileController.upload(multipartFile,request);
                if (json == null || !json.containsKey("url")) {
                    throw new CommunityException("上傳圖片失?。喉憫?yīng)數(shù)據(jù)異常");
                }
                return json.getString("url");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new CommunityException("生成二維碼失?。?+e.getMessage());
        } finally {
            if (httpURLConnection != null) {
                httpURLConnection.disconnect();
            }
        }
    }



}

2. 部分可自行調(diào)整的代碼解釋

FileController: 我自己的上傳圖片到服務(wù)器的類

mpAppId:  小程序appid

mpSecretId: 小程序 SecretId

pageHome: 要跳轉(zhuǎn)的小程序的頁面地址(例如: ‘pages/userInfo/userInfoHome’)

activeProfile: 我自己的判斷當(dāng)前運(yùn)行環(huán)境的配置(可以忽略)

@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 外部調(diào)用的方法,自定義自己需要傳入什么值

Long orderId : 這個(gè)是我為了生成二維碼路徑時(shí)攜帶的參數(shù)

HttpServletRequest request: 這個(gè)參數(shù),和二維碼生成邏輯沒有任何關(guān)系,我這里使用只是因?yàn)樯蟼鲌D片的地方需要這個(gè)值,這個(gè)比較冗余

scenes: 定義頁面地址攜帶什么參數(shù)

if ("prod-plus".equals(activeProfile)) {
    envVersion = "release";
}      這個(gè)是為了判斷生成什么環(huán)境的二維碼圖片(正式版/ 體驗(yàn)版) 
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 : 這個(gè)就是生成的二維碼圖片信息

下面的其他信息,都是為了把這個(gè)圖片的信息,上傳到自己項(xiàng)目中保存,最終返回圖片地址

byte[] imageData = baos.toByteArray();

// 簡單驗(yàn)證是否是有效圖片(可選)
if (imageData.length == 0) {
    throw new CommunityException("生成核銷二維碼失敗:返回空圖片數(shù)據(jù)");
}

MultipartFile multipartFile = new ByteArrayMultipartFile(
        orderId + "_mpqrcode",          // 表單字段名
        orderId + "_mpqrcode.png",      // 文件名
        "image/png",                  // 內(nèi)容類型
        imageData                  // 內(nèi)容
);
com.alibaba.fastjson.JSONObject json = fileController.upload(multipartFile,request);
if (json == null || !json.containsKey("url")) {
    throw new CommunityException("上傳二維碼失?。喉憫?yīng)數(shù)據(jù)異常");
}
return json.getString("url");

3.小程序中獲取攜帶的參數(shù)

以我上述的參數(shù)為例:(微信小程序使用的 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;
			  },
}

總結(jié) 

到此這篇關(guān)于Java生成微信小程序二維碼完整的文章就介紹到這了,更多相關(guān)Java生成微信小程序二維碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)五子棋AI算法

    Java實(shí)現(xiàn)五子棋AI算法

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)五子棋AI算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • SpringBoot連接MYSQL數(shù)據(jù)庫并使用JPA進(jìn)行操作

    SpringBoot連接MYSQL數(shù)據(jù)庫并使用JPA進(jìn)行操作

    今天給大家介紹一下如何SpringBoot中連接Mysql數(shù)據(jù)庫,并使用JPA進(jìn)行數(shù)據(jù)庫的相關(guān)操作。
    2017-04-04
  • SpringBoot整合Mybatis-Plus實(shí)現(xiàn)關(guān)聯(lián)查詢

    SpringBoot整合Mybatis-Plus實(shí)現(xiàn)關(guān)聯(lián)查詢

    Mybatis-Plus(簡稱MP)是一個(gè)Mybatis的增強(qiáng)工具,只是在Mybatis的基礎(chǔ)上做了增強(qiáng)卻不做改變,MyBatis-Plus支持所有Mybatis原生的特性,本文給大家介紹了SpringBoot整合Mybatis-Plus實(shí)現(xiàn)關(guān)聯(lián)查詢,需要的朋友可以參考下
    2024-08-08
  • springboot中undertow容器的使用及說明

    springboot中undertow容器的使用及說明

    Undertow是一個(gè)輕量級(jí)、高性能的Java?Web服務(wù)器,支持HTTP/2、WebSocket等,Spring?Boot中使用Undertow需要排除Tomcat依賴并添加Undertow依賴,Undertow的配置項(xiàng)包括訪問日志、緩沖區(qū)大小、解碼URL等,性能方面
    2025-11-11
  • MyBatis-Plus如何實(shí)現(xiàn)自動(dòng)加密解密

    MyBatis-Plus如何實(shí)現(xiàn)自動(dòng)加密解密

    這篇文章主要介紹了MyBatis-Plus實(shí)現(xiàn)自動(dòng)加密解密方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java如何處理json字符串value多余雙引號(hào)

    Java如何處理json字符串value多余雙引號(hào)

    這篇文章主要介紹了Java如何處理json字符串value多余雙引號(hào),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Springboot+MybatisPlus實(shí)現(xiàn)帶驗(yàn)證碼的登錄

    Springboot+MybatisPlus實(shí)現(xiàn)帶驗(yàn)證碼的登錄

    本文主要介紹了Springboot+MybatisPlus實(shí)現(xiàn)帶驗(yàn)證碼的登錄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • Java實(shí)現(xiàn)簡單樹結(jié)構(gòu)

    Java實(shí)現(xiàn)簡單樹結(jié)構(gòu)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡單樹結(jié)構(gòu)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Java Map.getOrDefault方法詳解

    Java Map.getOrDefault方法詳解

    Map.getOrDefault(Object key, V defaultValue)是Java中Map接口的一個(gè)方法,用于獲取指定鍵對應(yīng)的值,如果鍵不存在,則返回一個(gè)默認(rèn)值,這篇文章主要介紹了Java Map.getOrDefault方法詳解,需要的朋友可以參考下
    2024-01-01
  • Spring實(shí)戰(zhàn)之使用p:命名空間簡化配置操作示例

    Spring實(shí)戰(zhàn)之使用p:命名空間簡化配置操作示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之使用p:命名空間簡化配置操作,結(jié)合實(shí)例形式分析了spring p:命名空間簡單配置與使用操作技巧,需要的朋友可以參考下
    2019-12-12

最新評(píng)論

佳木斯市| 烟台市| 当雄县| 岑巩县| 长沙市| 应用必备| 义马市| 行唐县| 新乡县| 措美县| 仪征市| 息烽县| 迭部县| 乡宁县| 武夷山市| 新宁县| 澄江县| 阿图什市| 临朐县| 朝阳区| 宁晋县| 河北区| 扎赉特旗| 如东县| 逊克县| 汤阴县| 德州市| 安阳市| 柏乡县| 汕头市| 汝州市| 丰原市| 额尔古纳市| 四子王旗| 札达县| 会泽县| 罗源县| 徐水县| 安义县| 凤山县| 当涂县|