Java生成微信小程序二维码完整实例代码

 更新时间:2025年09月11日 10:48:51   作者:.也许.  
微信小程序是一种轻量级的应用程序,用户无需下载安装即可使用,因此受到了广泛的欢迎,这篇文章主要介绍了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 {

    @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) {
                // 读取错误流
                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;
			  },
}

总结 

到此这篇关于Java生成微信小程序二维码完整的文章就介绍到这了,更多相关Java生成微信小程序二维码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java类初始化顺序详解

    Java类初始化顺序详解

    这篇文章主要介绍了Java类初始化顺序详解,java语言在使用过程中最先开始就是初始化,在工作中如果遇到什么问题需 要定位往往到最后也可能是初始化的问题,因此掌握初始化的顺序很重要,需要的朋友可以参考下
    2023-08-08
  • springboot+mybatis+枚举处理器的实现

    springboot+mybatis+枚举处理器的实现

    在Spring boot项目开发中经常遇到需要使用枚举的场景,本文就介绍了springboot+mybatis+枚举处理器的实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • ConstraintValidator类如何实现自定义注解校验前端传参

    ConstraintValidator类如何实现自定义注解校验前端传参

    这篇文章主要介绍了ConstraintValidator类实现自定义注解校验前端传参的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Java内部类和异常类的概念以及使用

    Java内部类和异常类的概念以及使用

    这篇文章主要介绍了Java内部类和异常类的概念以及使用,文中有非常详细的代码以及注释,适合正在学习java基础的同学们使用,需要的朋友可以参考下
    2021-04-04
  • SpringCloud中的@FeignClient注解使用详解

    SpringCloud中的@FeignClient注解使用详解

    在Spring Cloud中使用Feign进行服务间的调用时,通常会使用@FeignClient注解来标记Feign客户端接口,这篇文章给大家介绍SpringCloud中的@FeignClient注解使用详解,感兴趣的朋友一起看看吧
    2025-06-06
  • java实现选课系统

    java实现选课系统

    这篇文章主要为大家详细介绍了java实现选课系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • Java的分支结构与循环你知道多少

    Java的分支结构与循环你知道多少

    这篇文章主要为大家详细介绍了Java的分支结构与循环,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • Java AtomicInteger类使用方法实例讲解

    Java AtomicInteger类使用方法实例讲解

    这篇文章主要介绍了Java AtomicInteger类使用方法实例讲解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • 若依框架多数据源切换方式

    若依框架多数据源切换方式

    这篇文章主要介绍了若依框架多数据源切换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java实现压缩 PDF文件大小的示例代码

    Java实现压缩 PDF文件大小的示例代码

    在日常工作中,我们经常会遇到 PDF 文件体积过大的问题,本文将为你揭示如何利用 Spire.PDF for Java 轻松实现 PDF 文件大小的优化与压缩,感兴趣的可以了解下
    2025-09-09

最新评论