有些场景需要生成带参数的小程序二维码,比如商城为每个商品生成小程序二维码,通过微信扫码直接跳转到该商品所在的展示页面。微信为开发者们提供了相应接口。
![]()
请求参数以及返回参数等请参考官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html
一、pom 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
二、后端接口示例
package club.jiajiajia.nwsp.controller;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class TestController {
static final String grant_type="grant_type";
static final String appid="appid";
static final String secret="secret";
/**
* 获取 acessToken
* @return
*/
private static String getAcessToken(){
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type="+grant_type+"&appid="+appid+"&secret="+secret;
RestTemplate restTemplate = new RestTemplate();
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
HttpEntity requestEntity = new HttpEntity(null, headers);
ResponseEntity<String> entity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class, new Object[0]);
String result = entity.getBody();
log.info("获取token:"+result);
Map<String, Object> resultObj = JSONObject.parseObject(result);
String accessToken = (String) resultObj.get("access_token");
return accessToken;
}
public static void main(String[] args) {
getminiqrQr("123");
}
/**
* @param sceneStr 微信二维码参数
*/
private static void getminiqrQr(String sceneStr) {
String acessToken = getAcessToken();
RestTemplate restTemplate = new RestTemplate();
InputStream inputStream = null;
OutputStream outputStream = null;
try {
String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+acessToken;
Map<String,Object> param = new HashMap<>();
// scene:参数
param.put("scene", sceneStr);
// page:微信小程序页面
param.put("page", "pages/productDetails");
param.put("width", 430);
param.put("auto_color", false);
Map<String,Object> line_color = new HashMap<>();
line_color.put("r", 0);
line_color.put("g", 0);
line_color.put("b", 0);
param.put("line_color", line_color);
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
HttpEntity requestEntity = new HttpEntity(param, headers);
// 请求数据
ResponseEntity<byte[]> entity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
byte[] result = entity.getBody();
// 如果生成失败,可以打印返回的错误信息
// System.out.println(new String(result,"utf-8"));
inputStream = new ByteArrayInputStream(result);
// 二维码存放路径
File file = new File("d:/data/1.png");
if (!file.exists()){
file.createNewFile();
}
outputStream = new FileOutputStream(file);
int len = 0;
byte[] buf = new byte[1024];
while ((len = inputStream.read(buf, 0, 1024)) != -1) {
outputStream.write(buf, 0, len);
}
outputStream.flush();
} catch (Exception e) {
log.error("调用小程序生成微信永久小程序码URL接口异常",e);
} finally {
if(inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(outputStream != null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
在springboot项目中测试,用到了RestTemplate等类。
通过该接口生成的小程序码,永久有效,数量暂无限制。用户扫描该码进入小程序后,开发者需在对应页面获取的码中 scene 字段的值,再做处理逻辑。使用如下代码可以获取到二维码中的 scene 字段的值。调试阶段可以使用开发工具的条件编译自定义参数 scene=xxxx 进行模拟,开发工具模拟时的 scene 的参数值需要进行 urlencode。同时需要注意,此接口的page参数中不能带任何参数,参数都在scene 参数中处理。
![]()
![]()
三、前端页面
Page({
onLoad: function(options) {
// options 中的 scene 需要使用 decodeURIComponent 才能获取到生成二维码时传入的 scene
var scene = decodeURIComponent(options.scene)
}
})