话不多说,直接上代码:
//这里单独拿出来了 就是通过appId和appSecret来获取accessToken
public String getAccessToken() {
Constant constant = constantService.selectConstantById(1);
String appId = constant.getConstant2();
// 小程序的 app secret (在微信小程序管理后台获取)
String secret = constant.getConstant3();
String grant_type = "client_credential";
//封装请求数据
String params = "grant_type=" + grant_type + "&secret=" + secret + "&appid=" + appId;
//发送GET请求
String sendGet = HttpClientUtils.doGet("https://api.weixin.qq.com/cgi-bin/token?" + params);
JSONObject jsonObject = JSONObject.parseObject(sendGet);
String accessToken = (String) jsonObject.get("access_token");
return accessToken;
}
/**
* 生成带参数的小程序二维码
* 并且存到用户信息中
* 如果已存在则直接返回
*
* @return
*/
@GetMapping("/getCodeUrl")
public Object getCodeUrl(Integer userId) {
try {
User user = userService.selectUserById(userId);
if (user == null) {
return AjaxResult.error("需要生成二维码的用户不存在");
}
if (!StringUtils.isEmpty(user.getCodeUrl())) {
return AjaxResult.success(user.getCodeUrl());
}
String accessToken = getAccessToken();
URL url = new URL("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");// 提交模式
// 发送POST请求必须设置如下两行
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
// 获取URLConnection对象对应的输出流
PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
// 发送请求参数
JSONObject paramJson = new JSONObject();
//二维码携带的参数
paramJson.put("scene", userId);
// paramJson.put("page", "pages/home/home?userId=" + userId);
//二维码跳转的路径
paramJson.put("page", "pages/index/index");
//二维码的尺寸
paramJson.put("width", 430);
paramJson.put("auto_color", true);
printWriter.write(paramJson.toString());
// flush输出流的缓冲
printWriter.flush();
//开始获取数据
BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());
//给文件重新命名
String newFileName = System.currentTimeMillis() + ".png";
//本地存放文件的路径
String nativePath = Global.getWebUploadPath() + File.separator
+ "thumbnail" + File.separator + "codeImg";
File nativeDir = new File(nativePath);
if (!nativeDir.exists()) {
nativeDir.mkdirs();
}
//网络访问路径
String webPath = Global.getWebURl() + "/thumbnail/" + "codeImg" + "/" + newFileName;
//保存到用户信息中
user.setCodeUrl(webPath);
userService.updateUser(user);
OutputStream os = new FileOutputStream(new File(nativePath + File.separator + newFileName));
int len;
byte[] arr = new byte[1024];
while ((len = bis.read(arr)) != -1) {
os.write(arr, 0, len);
os.flush();
}
os.close();
return AjaxResult.success(webPath);
} catch (Exception e) {
log.error("生成微信小程序二维码出现错误:" + e.getMessage());
return AjaxResult.error("生成微信小程序二维码出现错误" + e.getMessage());
}
}
大致讲一下流程,就是首先通过小程序的appId和appSecret来获取accessToken,然后通过这个accessToken就可以去生成小程序的二维码了。上面的例子生成的是带有参数的二维码,参数主要通过 paramJson.put("scene", userId)来实现,这里存放的是用户的id,因为每个用户id生成的二维码是相同的,所以生成以后我们存到用户信息里,下次使用就不需要再次生成,直接返回用户表里的二维码地址就可以。这里说一下碰到的两个小坑:
1、请求成功,生成了图片但是打不开,这种情况可以用notepad++以文本的形式打开,会提示错误码,然后根据这个错误码去查找问题。第一次错误的code码忘记记录了,百度一查告诉我没有传递参数,我就在paramJson.put("scene", 1);这里加了个1,然后再次生成,二维码就能以图片的形式打开了。
2、将图片存储到用户表后又测试了一遍,图片又打不开了,然后去网上查错误码,说是小程序没有正式上线导致无法正确的生成二维码。然后我把回调地址 从paramJson.put("page", "pages/home/home?userId=" + userId)改为paramJson.put("page", "pages/index/index")就又好了。
哪里写的不对,希望大神能够指正。大家一起进步。