好吧概页,其實這個通篇沒有啥大的知識點,但是細(xì)節(jié)上又不是那么簡單的练慕。所以這里整理一下以便以后使用惰匙。
首先簡單介紹下,微信小程序二維碼是微信官方提供的接口铃将,有多種實現(xiàn)方式项鬼。附上官網(wǎng)鏈接:
微信生成小程序二維碼鏈接
主要分兩種:
- 一種適用于需要的碼數(shù)量較少的業(yè)務(wù)場景。通過該接口生成的小程序碼劲阎,永久有效秃臣,有數(shù)量限制。重點是只能直接定位到小程序中某個頁面哪工,不能傳參數(shù),所以這個pass弧哎。
- 一種適用于需要的碼數(shù)量極多的業(yè)務(wù)場景雁比。通過該接口生成的小程序碼,永久有效撤嫩,數(shù)量暫無限制偎捎。只不過每分鐘調(diào)用次數(shù)有限,但是一分鐘好5000次,這個大多數(shù)時候都不會超出茴她,所以相當(dāng)于無限制寻拂。
我們這個項目需求是要每個碼帶參數(shù)的,所以選擇了第二種方式丈牢。
然後其實兩種方法使用的時候都需要一個必須的參數(shù):接口調(diào)用憑證——access_token.
這個參數(shù)是由appId和secret一起獲取的祭钉。至于這兩個參數(shù)怎么來的就沒法再往下說了。我今天的講解從 獲取access_token開始:
這個方法中的appId和secret是事先定義好的己沛。無論是靜態(tài)變量還是配置文件中都可以慌核。
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");
// 設(shè)置通用的請求屬性
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的響應(yīng)
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;
}
這個方法就是一個簡單的獲取憑證。這里做了個簡單的轉(zhuǎn)json獲取access_token的處理申尼,所以返回的直接是accesstoken的值垮卓。如果不做這步處理是一個map。一個是accesstoken一個是過期時間师幕。(這個token的過期時間大概是兩個小時左右粟按。反正我們項目是生成一次二維碼都重新獲取下這個token,省的過期了)
然後重點來了霹粥!用這個token去生成二維碼灭将。
話說這里比較復(fù)雜的是accesstoken要在路徑傳參,但是別的參數(shù)必須是post的body里以json的形式傳參蒙挑。所以這個其實是很麻煩的宗侦。如果想用postman測試這個接口如下寫法:
我上面例子中只有簡單的scene,如果還有page則繼續(xù)寫k-v對忆蚀。
然後這個要求放在java代碼中也略有不同矾利。下面附上java代碼:
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");// 提交模式
// 發(fā)送POST請求必須設(shè)置如下兩行
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
// 獲取URLConnection對象對應(yīng)的輸出流
PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
// 發(fā)送請求參數(shù)
JSONObject paramJson = new JSONObject();
paramJson.put("scene", "id="+id);
// paramJson.put("page", "pages/index/index"); //小程序暫未發(fā)布我沒有帶page參數(shù)
printWriter.write(paramJson.toString());
// flush輸出流的緩沖
printWriter.flush();
//開始獲取數(shù)據(jù)
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();
//實現(xiàn)了生成二維碼并保存在本地電腦的硬盤中。
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;
}
其實以上是兩個行為摻在一起的代碼馋袜。
上面這個方法我中間有段注釋:生成了二維碼并保存在了電腦中男旗。其實到這里就已經(jīng)實現(xiàn)了一個保存二維碼到服務(wù)器的功能。至此一種辦法就是直接返回這個圖片的可訪問路徑給前端欣鳖,前端直接獲取服務(wù)器資源就ok了察皇。
但是!泽台!我題目上就說了的返回給前端不是返回地址什荣,而是圖片直接返回去。所以才有了下面的代碼:其實就是讀取本地圖片再用response流的形式返回去怀酷。具體怎么做要看業(yè)務(wù)需求稻爬。主要是我們這個項目不打算讓前端可以直接獲取服務(wù)器資源(ip+端口+路徑+圖片名 訪問圖片的形式)。所以我這里相當(dāng)于多了一個過程蜕依。
然後可以開始判斷這個接口的實現(xiàn)遇到的坑了:
我之前都說了這個就是個簡單的接口訪問桅锄,難是不難琉雳,但是出于我的馬虎大意,所以也是調(diào)了一下午友瘤。下面一一道來翠肘。
- 作為一個面向百度的程序員,第一反應(yīng)是拿現(xiàn)成的辫秧,所以百度幾個帖子cv束倍,個個都出錯。最后發(fā)現(xiàn)百度靠前的幾個帖子代碼是一樣一樣的茶没。然後錯誤原因是人家用的是第一種獲取二維碼的方式肌幽,這種方式要求必須有page且沒有scene參數(shù)。反正就是接口路徑錯了抓半!
- 這兩個方法分開寫的一大問題:最開始獲取accesstoken的時候appid和secret都是參數(shù)的形式喂急。注意這個appid并沒有遵循常規(guī)的駝峰法。這個i是小寫的笛求。
- 建議多看看這個錯誤碼廊移。反正我在測試接口的時候,41001.44002探入,42001等等狡孔,什么xxx159(xxx是 我忘了是啥的)之類的好多都遇到了,面向錯誤碼編程蜂嗽,倒是沒必要記住苗膝,但是起碼知道出錯了去哪里查問題。下面附上微信錯誤碼頁面:
微信全局返回碼說明
然後這個簡單的小需求就實現(xiàn)了植旧,如果本文幫到了你記得點個喜歡點個關(guān)注辱揭。如果有什么問題也歡迎留言或者私信一起探討。另外祝大家工作順順利利病附!java技術(shù)交流群:130031711,歡迎各位萌新大佬踴躍加入问窃,共同學(xué)習(xí)進(jìn)步!