小程序二维码功能总结:
因为公司小程序通过二维码分享功能业务场景比较多,二维码功能开发过程中遇到的问题也比较多,
所以做个总结,有不妥之处希望大家指正。
微信提供生成的小程序二维码接口有三个分别是:
createWXAQRCode(普通的二维码-方形)
getWXACode (小程序二维码-圆形)
getWXACodeUnlimit(小程序二维码-圆形)
其中需要注意的地方,容易犯错的地方:
a、 调用的时候url都需要先去获取小程序对应的token,token获取正确是第一步。
b、 二维码接口参数设置这个地方坑很多。
1、比如参数path,这个参数设置的路径必须是小程序发布过的路径,没有发布过的路径就会报错,测试可以使用主页pages/index/index
2、参数width,设置二维码宽度,设置时注意它是String类型,这样写width="430" 而不是width=430。
c、通过什么方式调用这三个接口是比较重要,因为方式不同,接口返回的数据形式就不同,比如,
一种方式通过文件IO流把二维码是生成图片到本地了,但是怎么传给页面就是问题。
我更倾向于使用生成字节流的方式,这种数据形式容易被ImageIO图片io流获取,传送到oss或者直接
字节流形式返给前台比较方便。两种方式,我都会列举。具体可以看代码。
获取token的java代码:
/**
* access_token是公众号的全局唯一接口调用凭据
* */
public String getAccessToken(){
String accessToken = "";
String grantType = "client_credential";// 获取access_token填写client_credential
String appId ="xxxxxxxxxxxxx";// 第三方用户唯一凭证
String secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";// 第三方用户唯一凭证密钥,即appsecret
// 这个url链接地址和参数皆不能变
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" + grantType + "&appid=" + appId + "&secret="+ secret;
try {
URL urlGet = new URL(url);
HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
http.setRequestMethod("GET"); // 必须是get方式请求
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
http.connect();
InputStream is = http.getInputStream();
int size = is.available();
byte[] jsonBytes = new byte[size];
is.read(jsonBytes);
String message = new String(jsonBytes, "UTF-8");
// System.out.println("获取access_token返回的message:"+message);
JsonObject demoJson = JsonUtil.parseJson(message);
String jsonElement = demoJson.get("access_token").toString();
// System.out.println("获取access_token返回的json:"+demoJson);
accessToken=jsonElement;
accessToken = accessToken.replace("\"", "");
// System.out.println("新获取的access_token:"+accessToken);
is.close();
return accessToken;
}catch (Exception e){
e.printStackTrace();
System.out.println("获取access_token发生异常");
return null;
}
请求微信接口生成二维码的java代码:
拿getwxacodeunlimit举的例子,另外两个接口,套进去同样适用。
/**
* 获取小程序二维码
* @param AppID
* @param AppSecret
* @return
*/
public Map<String, Object> getMiniCode(String sceneStr) {
Map<String, Object> map = new HashMap<>();
try
{
//获取token
String accessToken = getAccessToken();
if(null==accessToken && accessToken.isEmpty()) {
map.put("resultDesc","获取token失败");
return map;
}
RestTemplate rest = new RestTemplate();
InputStream inputStream = null;
String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+accessToken;
Map<String,Object> param = new HashMap<>();
param.put("scene", sceneStr);
param.put("page", "pages/index/index");//此路径必须是小程序发布过的
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);
// LoggerUtil.DebugLogger.info("调用生成微信URL接口传参:" + param);
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
HttpEntity requestEntity = new HttpEntity(param, headers);
ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
// LoggerUtil.DebugLogger.info("调用小程序生成微信永久小程序码URL接口返回结果:" + entity.getBody());
byte[] result = entity.getBody();
// LoggerUtil.DebugLogger.info(Base64.encodeBase64String(result));
inputStream = new ByteArrayInputStream(result);
//开始获取数据-写本地
// BufferedInputStream bis = new BufferedInputStream(inputStream);
// OutputStream os = new FileOutputStream(new File("C:/Users/xuxiaomu/Desktop/abc.png"));//生成到本地路径
// int len;
// byte[] arr = new byte[1024];
// while ((len = bis.read(arr)) != -1)
// {
// os.write(arr, 0, len);
// os.flush();
// }
// os.close();
// 根据时间产生路径
long ymdhms = DateUtil.getYYYYMMDDHHmmssByLong(new Date());
String ext = "png";
String userCertificateJPGName = sceneStr + "_" + ymdhms + "."+ext; // 用户的证书存放目录+文件名
String filePath ="ossPath"+userCertificateJPGName;//根据工具类设置上传oss的路径
BufferedImage bufferedImage = ImageIO.read(inputStream);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, ext, os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
//下面这个方法是我根据公司需要把图片二进制流写到oss服务上了,返回访问的路径。前端直接访问oss存的图片路径就可以看到二维码。
//具体情况具体分析,拿到的是图片的字节类型输入流,大家可以自行处理,比如上传到项目的静态文件夹下。然后通过https://域名:端口号/项目名称/图片名称.png就可以访问了
String miniCodeUrl = OssOperUtil.ossUploadInputStream(is, filePath);
map.put("codeUrl", codeUrl);return map;
}
catch (Exception e)
{
e.printStackTrace();return null;
}
}