前期准备:小程序AppId,小程序AppSecret
微信接口文档:获取不限制的小程序码 | 微信开放文档
通过AppId和AppSecret,请求微信官网接口获取access_token,说到这个access_token,鸭蛋的就是巨坑,官网上说获取一次后,有效期是两个小时
看见它两个小时后才过期,我就寻思着把它放进redis里面,后面可以直接用,结果经常没几分钟就过期了,害我拿了个过期access_token去获取二维码,获取二维码的接口又不报错,只是给我返回了一个损坏打不开的图片,搞得我测试的时候,一直拿不到正确的二维码,又不知道哪里出问题,百度查来查去,整个人都傻了,后面不停的调试,才知道是access_token有问题,所以现在不存缓存了,每次都重新请求获取。
回归正题,获取access_token,我是通过Https网络请求方式获取,获取access_token用Get请求
官方文档:获取接口调用凭据 | 微信开放文档
// 拼接url发起请求到微信认证服务器获取token
String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"
.replace("APPID", "小程序AppId")
.replace("APPSECRET", "小程序AppSecret");
// 发送请求获取access_token
String atResult = this.httpClientGet(tokenUrl);
随后解析结果,httpClientGet返回的是一个字符串格式化后的JSON串,我是通过fastJosn包的JSONObject.parseObject 方法解析。
具体JSON有哪些值,看官方文档,如果发送错误,会返回错误码,自己去官网文档对照错误码什么意思。
JSONObject tokenObj = JSONObject.parseObject(atResult);
if (StringUtils.isNotBlank(tokenObj.getString("errcode"))) {
throw new Exception("获取access_token失败");
}
//获取accessToken
String accessToken = tokenObj.getString("access_token");
随后通过access_token获取小程序二维码,这个用Post请求
// 获取小程序码
String codeUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN"
.replace("ACCESS_TOKEN", accessToken);
Post请求参数,需要注意check_path 和 env_version 两个参数,发布版本上生产环境时需要删掉,其他请求参数可以看官网文档
Map<String, Object> map = new HashMap<>();
try {
// 设置路径参数,类似 https://xxx.com?a=1&b=2,请求路径问号后面的参数,得用encodeURIComponent进行转码,前端用decodeURIComponent方法即可还原
map.put("scene", URLEncoder.encode("a=1&b=2", "utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 跳转路径
map.put("page", "pages/tabbar/index/index");
// 是否强制验证路径是否存在
map.put("check_path", false);
// 当前环境:正式版为 "release",体验版为 "trial",开发版为 "develop"。默认是正式版。 默认下面这句代码是注释的,发布版本上生产环境时要注释这句代码
map.put("env_version", "develop");
最后发起请求,获取图片二维码,我这里是转成了base64格式,然后传给前端,前端解析成图片
请求返回的结果,如果请求正常,是直接返回图片资源,不然会返回错误信息
try {
// 请求方法返回字节数组,转成base64格式返回前端
String base64 = Base64.getEncoder().encodeToString(this.httpClientPost(codeUrl, map));
return base64;
} catch (Exception e) {
e.printStackTrace();
return null;
}
网络请求我是用HttpClient请求,可以换成其他网络请求方式,上面的代码中:httpClientGet,httpClientPost是经过我封装的,替换成你们的网络请求方式就可以了
具体HttpClient怎么用,可以百度,用起来不困难,不过有个地方得提醒一句,HttpClient请求后,最好是把返回值转成bytes返回,或者转成字符串返回,因为我们请求完肯定会关闭流对象,很容易出问题。
码字不易,于你有利,勿忘点赞
大鹏一日同风起,扶摇直上九万里