原文:https://www.jianshu.com/p/6e05df377e52
微信生成小程序二维码链接
主要分两种:
- 一种适用于需要的码数量较少的业务场景。通过该接口生成的小程序码,永久有效,有数量限制。重点是只能直接定位到小程序中某个页面,不能传参数,所以这个pass。
- 一种适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制。只不过每分钟调用次数有限,但是一分钟好5000次,这个大多数时候都不会超出,所以相当于无限制。
我们选择了第二种方式。
然後其实两种方法使用的时候都需要一个必须的参数:接口调用凭证——access_token.
这个参数是由appId和secret一起获取的。至于这两个参数怎么来的就没法再往下说了。我今天的讲解从 获取access_token开始:
这个方法中的appId和secret是事先定义好的。无论是静态变量还是配置文件中都可以。
public static String getAccessToken() throws Exception { String requestUrl ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret; URL url = new URL(requestUrl); // 打开和URL之间的连接 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); // 设置通用的请求属性 connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Connection", "Keep-Alive"); connection.setUseCaches(false); connection.setDoOutput(true); connection.setDoInput(true); // 得到请求的输出流对象 DataOutputStream out = new DataOutputStream(connection.getOutputStream()); out.writeBytes(""); out.flush(); out.close(); // 建立实际的连接 connection.connect(); // 定义 BufferedReader输入流来读取URL的响应 BufferedReader in = null; if (requestUrl.contains("nlp")) in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "GBK")); else in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); String result = ""; String getLine; while ((getLine = in.readLine()) != null) { result += getLine; } in.close(); JSONObject jsonObject = JSON.parseObject(result); String accesstoken=jsonObject.getString("access_token"); return accesstoken; }
然後重点来了!用这个token去生成二维码。
话说这里比较复杂的是accesstoken要在路径传参,但是别的参数必须是post的body里以json的形式传参。所以这个其实是很麻烦的。如果想用postman测试这个接口如下写法:
public String getQRCode(HttpServletResponse response,Long id, HttpServletRequest request) { try { String wxCodeURL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+getAccessToken(); URL url = new URL(wxCodeURL); 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", "id="+id); // paramJson.put("page", "pages/index/index"); //小程序暂未发布我没有带page参数 printWriter.write(paramJson.toString()); // flush输出流的缓冲 printWriter.flush(); //开始获取数据 BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream()); OutputStream os = new FileOutputStream(new File("D:/wechat/qr"+id+".png")); int len; byte[] arr = new byte[1024]; while ((len = bis.read(arr)) != -1) { os.write(arr, 0, len); os.flush(); } os.close(); //实现了生成二维码并保存在本地电脑的硬盘中。 File file = new File("D:/wechat/qr"+id+".png"); FileInputStream fis = new FileInputStream(file); long size = file.length(); byte[] temp = new byte[(int) size]; fis.read(temp, 0, (int) size); fis.close(); byte[] data = temp; response.setContentType("image/png"); OutputStream out = response.getOutputStream(); out.write(data); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } return null; }
其实以上是两个行为掺在一起的代码。
上面这个方法我中间有段注释:生成了二维码并保存在了电脑中。其实到这里就已经实现了一个保存二维码到服务器的功能。至此一种办法就是直接返回这个图片的可访问路径给前端,前端直接获取服务器资源就ok了。
但是!!我题目上就说了的返回给前端不是返回地址,而是图片直接返回去。所以才有了下面的代码:其实就是读取本地图片再用response流的形式返回去。具体怎么做要看业务需求。主要是我们这个项目不打算让前端可以直接获取服务器资源(ip+端口+路径+图片名 访问图片的形式)。所以我这里相当于多了一个过程。
然後可以开始判断这个接口的实现遇到的坑了:
我之前都说了这个就是个简单的接口访问,难是不难,但是出于我的马虎大意,所以也是调了一下午。下面一一道来。
- 作为一个面向百度的程序员,第一反应是拿现成的,所以百度几个帖子cv,个个都出错。最后发现百度靠前的几个帖子代码是一样一样的。然後错误原因是人家用的是第一种获取二维码的方式,这种方式要求必须有page且没有scene参数。反正就是接口路径错了!
- 这两个方法分开写的一大问题:最开始获取accesstoken的时候appid和secret都是参数的形式。注意这个appid并没有遵循常规的驼峰法。这个i是小写的。
- 建议多看看这个错误码。反正我在测试接口的时候,41001.44002,42001等等,什么xxx159(xxx是 我忘了是啥的)之类的好多都遇到了,面向错误码编程,倒是没必要记住,但是起码知道出错了去哪里查问题。下面附上微信错误码页面:
微信全局返回码说明
请发表评论