前言
先介紹一下項目場景,主要是通過微信小程序二維碼裂變分享
,每個賬號有專屬邀請二維碼,分享出去,有新人掃碼入駐,就可以得到現(xiàn)金獎勵或紅包獎勵。當(dāng)然,產(chǎn)品設(shè)計會更豐富,不止有裂變模式,還有渠道推廣模式,還有各種獎勵規(guī)則,但核心實現(xiàn)都是生成二維碼。對于如何生成微信小程序二維碼
,本文一共列舉了5種
實現(xiàn)方式,其中第1、2種是網(wǎng)上常見的方式,第3、4、5種封裝的更為優(yōu)雅,文末可打包下載開箱即用的全套源碼,我更期待老鐵的文末 投票
:哪種方式你更喜歡?
先看官網(wǎng)
項目主要用的是微信官方提供的服務(wù)端能力,考慮到涉及secret和token等安全問題,所以從架構(gòu)上設(shè)計的調(diào)用鏈路為
:前端->后端API->微信API。裂變的場景決定要選擇獲取不限制的小程序碼
接口,永久有效,數(shù)量暫無限制,接口英文名:getUnlimitedQRCode。
官方地址:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getUnlimitedQRCode.html
一、JDK自帶的URLConnection方式
在網(wǎng)上常見的方式,這是從 JDK1.1 開始就自帶的Http請求方式,核心代碼如下:
public byte[] getWechatQrcodeByHttpURL(String url, Map<String, Object> body) {
HttpURLConnection httpURLConnection = null;
try {
httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
httpURLConnection.setRequestMethod("POST");
// 發(fā)送POST請求必須設(shè)置如下兩行
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
// 獲取URLConnection對象對應(yīng)的輸出流
PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
// 發(fā)送請求參數(shù)
printWriter.write(JSONObject.toJSONString(body));
// flush輸出流的緩沖
printWriter.flush();
//開始獲取數(shù)據(jù)
try (InputStream inputStream = httpURLConnection.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
return out.toByteArray();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
return null;
}
JDK自帶的方式,功能雖然可以實現(xiàn),但代碼看上去確實跟不上時代發(fā)展了!
二、Apache的HttpClient方式
HttpClient 相比于 JDK 自帶的 URLConnection方式,代碼做了封裝,可讀性和簡潔度都顯著提升!核心代碼如下:
public byte[] getWechatQrcodeByHttpClient(String url, Map<String, Object> body) {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost(url);
try {
StringEntity entity = new StringEntity(JSONObject.toJSONString(body));
entity.setContentType("image/png");
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);
try (InputStream inputStream = response.getEntity().getContent();
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
return out.toByteArray();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Maven依賴:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
</dependency>
三、okhttp3方式
okhttp3是Square公司開發(fā),用于替代 HttpUrlConnection和Apache HttpClient方式,優(yōu)雅的 API 設(shè)計,且鏈?zhǔn)秸{(diào)用,讓你順滑到底!
核心代碼如下:
public byte[] getWechatQrcodeByOkhttp3(String url, Map<String, Object> body) {
OkHttpClient client = new OkHttpClient().newBuilder().build();
okhttp3.MediaType mediaType = okhttp3.MediaType.parse("application/json");
RequestBody requestBody = RequestBody.create(mediaType, JSONObject.toJSONString(body));
Request request = new Request.Builder().url(url).method("POST", requestBody).build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().bytes();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Maven依賴:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.2</version>
</dependency>
四、Unirest方式
okhttp3方式其實不管是性能還是代碼的鏈?zhǔn)秸{(diào)用,都已經(jīng)非常優(yōu)秀。但作為底層基于Apache HttpClient方式的unirest-java,提供了更為便捷、鏈?zhǔn)秸{(diào)用、功能強大的API用于http請求!核心代碼如下(一行代碼
搞定,屌爆了?。。。?/p>
public byte[] getWechatQrcodeByUnirest(String url, Map<String, Object> body) {
return Unirest.post(url).body(JSONObject.toJSONString(body)).asBytes().getBody();
}
Maven依賴:
<dependency>
<groupId>com.konghq</groupId>
<artifactId>unirest-java</artifactId>
<version>3.11.11</version>
</dependency>
五、RestTemplate方式
我之前寫過一篇博文對RestTemplate.exchange
結(jié)合案例進行了詳細(xì)的介紹:RestTemplate.exchange各種用法(包括泛型等 --全),推薦閱讀!
這也是我們項目實際使用的方式,使用Spring框架開發(fā),還是強烈推薦使用Spring的RestTemplate
,它是對于其它方式的高級封裝,內(nèi)部可以配置ClientHttpRequestFactory來指定底層請求方式:
- 指定為SimpleClientHttpRequestFactory,則內(nèi)部使用JDK自帶的HttpURLConnection方式
- 指定為HttpComponentsClientHttpRequestFactory,則內(nèi)部使用Apache HttpClient方式
- 指定為OkHttp3ClientHttpRequestFactory,則內(nèi)部使用okhttp3方式
核心代碼也是一行:
public byte[] getWechatQrcodeByRestTemplate(String url, Map<String, Object> body) {
return restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(body, null), byte[].class).getBody();
}
另外,RestTemplate在構(gòu)造函數(shù)中默認(rèn)增加了ByteArrayHttpMessageConverter
,可以讀取和寫入字節(jié)數(shù)組的HttpMessageConverter的實現(xiàn),默認(rèn)情況下,此轉(zhuǎn)換器支持所有媒體類型(media types)。
其它細(xì)節(jié)
getAccessToken
這是接口調(diào)用憑證,用restTemplate調(diào)用也是非常簡潔,核心代碼如下:
private String wechatQrcodeUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=";
private String appid = "替換成你的appid";
private String s = "替換成你的secret";
public String getAccessToken() {
String url = String.format(wechatAccessTokenUrl, appid, s);
Map<String, String> responseBody = restTemplate.exchange(url, HttpMethod.GET, null, new ParameterizedTypeReference<Map<String, String>>() {}).getBody();
if (responseBody == null || responseBody.get("errcode") != null) {
// 獲取失敗
System.out.println("getAccessToken失?。? + (responseBody == null ? "null" : responseBody.toString()));
return null;
}
return responseBody.get("access_token");
}
對于access_token,建議保存到redis,2小時過期后再獲取
構(gòu)建參數(shù)map
body 就是參數(shù)Map,需要根據(jù)實際情況自行設(shè)定:
Map<String,Object> body = new HashMap<>();
// 場景碼,與前端約定,最終是需要前端解析
body.put("scene", scene);
// 正式版為 "release",體驗版為 "trial",開發(fā)版為 "develop"。默認(rèn)是正式版。
body.put("env_version", envVersion);
// 透明,根據(jù)你的場景自行設(shè)置body參數(shù)
body.put("is_hyaline", true);
byte[]數(shù)組
為什么要先得到byte[]數(shù)組?
,因為我們需要先判斷返回結(jié)果是否包含errcode
,如果不包含,才是圖片Buffer
!
如果不包含errorCode,那么byte[]數(shù)組不管是保存本地,還是轉(zhuǎn)成Base64,或者上傳到OSS,都非常濕滑了!
- 保存本地
private void saveQrCodeToLocal(byte[] bytes) {
try {
InputStream inputStream = new ByteArrayInputStream(bytes);
FileOutputStream out = new FileOutputStream("d:\\test.png");
byte[] buffer = new byte[8192];
int bytesRead = 0;
while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
out.write(buffer, 0, bytesRead);
}
out.flush();
inputStream.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
- Base64
Base64.getEncoder().encodeToString(bytes);
- 上傳OSS
這是我們項目使用的, 底層做了封裝,直接傳byte[]即可,非常方便!
源碼下載
源碼都是經(jīng)過實測的,可以直接使用!
下載地址:https://download.csdn.net/download/scm_2008/87398320文章來源:http://www.zghlxwxcb.cn/news/detail-776832.html
?? 博客主頁:https://blog.csdn.net/scm_2008
?? 歡迎點贊?? 收藏 ?留言?? 如有錯誤敬請指正!
?? 本文由 天罡gg 原創(chuàng),首發(fā)于 CSDN博客??
?? 停下休息的時候不要忘了別人還在奔跑,希望大家抓緊時間學(xué)習(xí),全力奔赴更美好的生活文章來源地址http://www.zghlxwxcb.cn/news/detail-776832.html
到了這里,關(guān)于Java生成微信小程序二維碼,5種實現(xiàn)方式,一個比一個簡單的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!