java生成微信小程序二維碼并保存/返回給前端

好吧概页,其實這個通篇沒有啥大的知識點,但是細(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測試這個接口如下寫法:


路徑上傳accesstoken

body中json的形式傳參

我上面例子中只有簡單的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)了一下午友瘤。下面一一道來翠肘。

  1. 作為一個面向百度的程序員,第一反應(yīng)是拿現(xiàn)成的辫秧,所以百度幾個帖子cv束倍,個個都出錯。最后發(fā)現(xiàn)百度靠前的幾個帖子代碼是一樣一樣的茶没。然後錯誤原因是人家用的是第一種獲取二維碼的方式肌幽,這種方式要求必須有page且沒有scene參數(shù)。反正就是接口路徑錯了抓半!
  2. 這兩個方法分開寫的一大問題:最開始獲取accesstoken的時候appid和secret都是參數(shù)的形式喂急。注意這個appid并沒有遵循常規(guī)的駝峰法。這個i是小寫的笛求。
  3. 建議多看看這個錯誤碼廊移。反正我在測試接口的時候,41001.44002探入,42001等等狡孔,什么xxx159(xxx是 我忘了是啥的)之類的好多都遇到了,面向錯誤碼編程蜂嗽,倒是沒必要記住苗膝,但是起碼知道出錯了去哪里查問題。下面附上微信錯誤碼頁面:
    微信全局返回碼說明

然後這個簡單的小需求就實現(xiàn)了植旧,如果本文幫到了你記得點個喜歡點個關(guān)注辱揭。如果有什么問題也歡迎留言或者私信一起探討。另外祝大家工作順順利利病附!java技術(shù)交流群:130031711,歡迎各位萌新大佬踴躍加入问窃,共同學(xué)習(xí)進(jìn)步!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末完沪,一起剝皮案震驚了整個濱河市域庇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌覆积,老刑警劉巖听皿,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異宽档,居然都是意外死亡写穴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門雌贱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啊送,“玉大人,你說我怎么就攤上這事欣孤〔雒唬” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵降传,是天一觀的道長篷朵。 經(jīng)常有香客問我,道長婆排,這世上最難降的妖魔是什么声旺? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮段只,結(jié)果婚禮上腮猖,老公的妹妹穿的比我還像新娘。我一直安慰自己赞枕,他們只是感情好澈缺,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炕婶,像睡著了一般姐赡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上柠掂,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天项滑,我揣著相機(jī)與錄音,去河邊找鬼涯贞。 笑死枪狂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肩狂。 我是一名探鬼主播摘完,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼傻谁!你這毒婦竟也來了孝治?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤审磁,失蹤者是張志新(化名)和其女友劉穎谈飒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體态蒂,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡杭措,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了钾恢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片手素。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡鸳址,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出泉懦,到底是詐尸還是另有隱情稿黍,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布崩哩,位于F島的核電站巡球,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏邓嘹。R本人自食惡果不足惜酣栈,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望汹押。 院中可真熱鬧矿筝,春花似錦、人聲如沸鲸阻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸟悴。三九已至陈辱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間细诸,已是汗流浹背沛贪。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留震贵,地道東北人利赋。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像猩系,于是被迫代替她去往敵國和親媚送。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345