java后端生成微信小程序二维码保存本地,将图片路径返回给前端
获取小程序码
官方地址
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/qr-code.html
为满足不同需求和场景,这里提供了两个接口,开发者可挑选适合自己的接口。
- 接口 A: 适用于需要的码数量较少的业务场景
- 生成小程序码,可接受 path 参数较长,生成个数受限,数量限制见 注意事项,请谨慎使用。
- 接口 B:适用于需要的码数量极多的业务场景
- 生成小程序码,可接受页面参数较短,生成个数不受限
接口B为例:
请求地址
POST https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN
可以看到请求地址需要access_token,所以我们需要先获取
access_token
官方地址 https://developers.weixin.qq.com/doc/offiaccount/WeChat_Invoice/Nontax_Bill/API_list.html#1.1%20%E8%8E%B7%E5%8F%96access_token
请求地址
请求URL:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
请求方法:GET
先上获取access_token 与 获取二维码的代码:
package com.yami.shop.api.Util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; @Component @Slf4j public class WxQrCode { //获取AccessToken路径 private static final String AccessToken_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";//小程序id //获取二维码路径 private static final String WxCode_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN";//小程序密钥 /** * 用于获取access_token * @return access_token * @throws Exception */ public static String getAccessToken(String appid,String secret) throws Exception { String requestUrl = AccessToken_URL.replace("APPID",appid).replace("APPSECRET",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; } /* * 获取 二维码图片 * */ public static String getminiqrQr(String accessToken,String uploadPath, HttpServletRequest request) { String ctxPath = uploadPath; String fileName="twoCode.png"; String bizPath = "files"; String nowday = new SimpleDateFormat("yyyyMMdd").format(new Date()); String ppath =ctxPath + File.separator + bizPath + File.separator + nowday; File file = new File(ctxPath + File.separator + bizPath + File.separator + nowday); if (!file.exists()) { file.mkdirs();// 创建文件根目录 } String savePath = file.getPath() + File.separator + fileName; String qrCode = bizPath + File.separator + nowday+ File.separator + fileName; // if (ppath.contains("\\")) { // ppath = ppath.replace("\\", "/"); // } if (qrCode.contains("\\")) { qrCode = qrCode.replace("\\", "/"); } // String codeUrl=ppath+"/twoCode.png"; System.out.print(qrCode); System.out.print(savePath); try { // URL url = new URL("https://api.weixin.qq.com/wxa/getwxacode?access_token="+accessToken); String wxCodeURL = WxCode_URL.replace("ACCESS_TOKEN",accessToken); URL url = new URL(wxCodeURL); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setRequestMethod("POST");// 提交模式 // conn.setConnectTimeout(10000);//连接超时 单位毫秒 // conn.setReadTimeout(2000);//读取超时 单位毫秒 // 发送POST请求必须设置如下两行 httpURLConnection.setDoOutput(true); httpURLConnection.setDoInput(true); // 获取URLConnection对象对应的输出流 PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream()); // 发送请求参数 JSONObject paramJson = new JSONObject(); paramJson.put("scene", "1234567890"); // paramJson.put("page", "pages/index/index"); //小程序暂未发布我没有带page参数 paramJson.put("width", 430); paramJson.put("is_hyaline", true); paramJson.put("auto_color", true); /** * line_color生效 * paramJson.put("auto_color", false); * JSONObject lineColor = new JSONObject(); * lineColor.put("r", 0); * lineColor.put("g", 0); * lineColor.put("b", 0); * paramJson.put("line_color", lineColor); * */ printWriter.write(paramJson.toString()); // flush输出流的缓冲 printWriter.flush(); //开始获取数据 BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream()); OutputStream os = new FileOutputStream(new File(savePath)); int len; byte[] arr = new byte[1024]; while ((len = bis.read(arr)) != -1) { os.write(arr, 0, len); os.flush(); } os.close(); } catch (Exception e) { e.printStackTrace(); } return qrCode; } }
controller层 我是从控制层将参数带过去的
package com.yami.shop.api.owneruser.controller; import com.alibaba.fastjson.JSONObject; import com.yami.shop.api.Util.WxQrCode; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.io.IOException; @RequestMapping("/owner/code") @RestController public class WxQrCodeController { // @Value("${ma.appid}") private String APIKEY="wxab03e9b278534a80";//小程序id // @Value("${ma.secret}") private String SECRETKEY="b992f830ec418093323d487ddd109e9f";//小程序密钥 @Value("${file.path.upload}") private String uploadPath; /** * 接收二维码 * @param request * @return * @throws IOException */ @GetMapping(value="/code") public Object twoCode(HttpServletRequest request) throws IOException { JSONObject data=new JSONObject(); String accessToken = null; try{ accessToken = WxQrCode.getAccessToken(APIKEY,SECRETKEY); System.out.println("accessToken;"+accessToken); String twoCodeUrl = WxQrCode.getminiqrQr(accessToken,uploadPath,request); data.put("twoCodeUrl", twoCodeUrl); return data; }catch (Exception e){ e.printStackTrace(); } return null; } }
获取二维码请求参数
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
access_token | string | 是 | 接口调用凭证 | |
scene | string | 是 | 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~ ,其它字符请自行编码为合法字符(因不支持% ,中文无法使用 urlencode 处理,请使用其他编码方式) |
|
page | string | 主页 | 否 | 必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index , 根路径前不要填加 / ,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面 |
width | number | 430 | 否 | 二维码的宽度,单位 px,最小 280px,最大 1280px |
auto_color | boolean | false | 否 | 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调,默认 false |
line_color | Object | {"r":0,"g":0,"b":0} | 否 | auto_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示 |
is_hyaline | boolean | false | 否 | 是否需要透明底色,为 true 时,生成透明底色的小程序 |
返回值
Buffer (返回的图片 Buffer)
异常返回
Object
JSON
属性 | 类型 | 说明 |
---|---|---|
errcode | number | 错误码 |
errmsg | string | 错误信息 |
errcode 的合法值
值 | 说明 | 最低版本 |
---|---|---|
45009 | 调用分钟频率受限(目前5000次/分钟,会调整),如需大量小程序码,建议预生成。 | |
41030 | 所传page页面不存在,或者小程序没有发布 |
返回值说明
如果调用成功,会直接返回图片二进制内容,如果请求失败,会返回 JSON 格式的数据。
--------------------------------请多多指教