微信公衆號開發(三)生成帶參數的二維碼

微信公衆號開發之生成帶參數的二維碼
 
作微信公衆號開發的人員都知道用戶海報做爲公衆號吸引用戶是常見的渠道,那麼我就說說這個海報的生成。
 
看了好多公衆號發現他們的海報都是大同小異,一個漂亮的背景+本身的頭像+專屬二維碼。
 背景就不闡述了,用戶的頭像能夠由公衆號開發文檔提供的方式獲取(根據用戶的openId),今天主要講用戶的專屬二維碼
所謂專屬即使是一對一的。
 
二維碼分爲兩種,臨時二維碼和永久二維碼
     /*生成永久二維碼*/
      public static String getPerpetualQR(String account ){
 
          //獲取數據的地址(微信提供)
          String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token= access_token (變量) ";
 
          //發送給微信服務器的數據
          String jsonStr = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\":{\"scene\": {\"scene_id\": " + account + "}}}" ;
 
          //post請求獲得返回數據(這裏是封裝過的,就是普通的java post請求)
          String response = RequestMethod.sendPost( jsonStr , url );
           return response .toString();
     }
     這裏解釋一下發送的數據:
      action_name:能夠識別你要獲取的二維碼是永久性仍是臨時的( QR_LIMIT_SCENE :永久;QR_SCENE:臨時),
      scene_id:要傳入的參數
 
     服務器的返回數據
     {"ticket":"gQHp7zoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0tEc29Sd0xsU2VzdzVHWTA2UmZSAAIEBQ5hVwMEAAAAAA==",
     "url":"http:\/\/weixin.qq.com\/q\/KDsoRwLlSesw5GY06RfR"}
      ticket:與上面傳入的參數是一一對應的,因此上面傳入的參數最好是惟一的能夠標識的數據,並且用戶在掃二維碼的時候,若是是掃帶有參數的二維碼,那麼微信服務器會返回這個ticket,具體能夠看上一節(用戶關注)
      url:二維碼地址,後臺能夠根據這個地址將二維碼下載到本地,具體的方法我會在下面提供一個。
        
     到這裏你們應該會疑問上面的 access_token (變量),這個是和微信服務器打交道的識別數據,這個數據必須有效才能進行一切的獲取數據操做,去開發文檔上看能夠了解到這個數據由微信服務器提供,2個小時過時,可是每兩個小時之間會有一個過渡期,新老 access_token 均可以使用,不過這個過渡期的時間確實個謎,本人也未研究過,只是不少網友說這個過渡期是3-5分鐘。這裏有個很大的坑,就是token沒有過時,可是微信服務器返回token失效,具體的解決方案待我下一節詳說。
          以上是永久二維碼的獲取步驟,可是永久二維碼有一個缺陷,就是數量有限(目前最多爲10萬個),臨時二維碼會更多,可是是不是無限的,這個待定。。。
     
      /*生成臨時二維碼*/
      public static String getTemporaryQR(String scene_id ){
          //獲取數據的地址(微信提供)
          String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token= access_token (變量) ";
 
          //發送給微信服務器的數據
          String jsonStr = "{\"expire_seconds\": 2592000,\"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": " + scene_id + "}}}" ;
 
           //將獲得的字符串轉化成json對象
          String response = RequestMethod.sendPost( jsonStr , url );
           return response.toString();
     }
     
     發送的數據相對永久二維碼多了一個 expire_seconds,這是設定二維碼的有效期,以秒爲單位,最多不超過30天,而且 action_name須要改爲 QR_SCENE。
     
     服務器的返回數據
     {"ticket":"gQFt7zoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0F6dFktTVhsSV90YXNVX1ZtUlhSAAIE5hxiVwMEPAAAAA==",
      "expire_seconds":60,
      "url":"http:\/\/weixin.qq.com\/q\/AztY-MXlI_tasU_VmRXR"}
 
     返回的數據相對永久二維碼就是多了一個expire_seconds,這個是有效期,過時掃碼無效。
 
如今你們都知道了永久二維碼和臨時二維碼之間的區別了,至於使用哪種,根據需求變化。
參數與ticket之間是一一對應的,這也就達到了生成用戶海報的專屬二維碼了,至於這個參數的選定,本人能夠給一個建議,將用戶的openId+當前時間做爲參數,返回的ticket和用戶就能夠達到一一對應的想過了,當二維碼過時,數據庫更新ticket這個數據就能夠了,或者用戶每次獲取海報的時候就從新更新一個二維碼,反正臨時的不少。其餘用戶掃這個二維碼的時候微信會將二維碼的ticket返回給咱們,再根據ticket和openId的對應關係就能夠知道當前被掃用戶是誰了。
     
     下面提供一些方法:
      
     //post請求
      public static String sendPost(String param , String url ) {
          PrintWriter out = null ;
          BufferedReader in = null ;
          String result = "" ;
           try {
              URL realUrl = new URL( url );
               // 打開和URL之間的鏈接
              URLConnection conn = realUrl .openConnection();
               // 設置通用的請求屬性
               conn .setRequestProperty( "accept" , "*/*" );
               conn .setRequestProperty( "connection" , "Keep-Alive" );
               conn .setRequestProperty( "user-agent" ,
                         "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)" );
               // 發送POST請求必須設置以下兩行
               conn .setDoOutput( true );
               conn .setDoInput( true );
               // 獲取URLConnection對象對應的輸出流
               // out = new PrintWriter(conn.getOutputStream());
               out = new PrintWriter( new OutputStreamWriter(
                         conn .getOutputStream(), "utf-8" ));
               // 發送請求參數
               out .print( param );
               // flush輸出流的緩衝
               out .flush();
               // 定義BufferedReader輸入流來讀取URL的響應
               in = new BufferedReader( new InputStreamReader(
                         conn .getInputStream(), "UTF-8" ));
              String line ;
               while (( line = in .readLine()) != null ) {
                    result += line ;
              }
          } catch (Exception e ) {
              System. out .println( "發送 POST 請求出現異常!" + e );
               e .printStackTrace();
          }
           // 使用finally塊來關閉輸出流、輸入流
           finally {
               try {
                    if ( out != null ) {
                         out .close();
                   }
                    if ( in != null ) {
                         in .close();
                   }
              } catch (IOException ex ) {
                    ex .printStackTrace();
              }
          }
           return result ;
     }
 
 
//根據url下載文件,參數(文件網址,存文件的本地地址)     
public static Boolean downloadFile(String urlString , String filePath ){
         // 構造URL
         URL url ;
           try {
               url = new URL( urlString );
               // 打開鏈接
              URLConnection con ;
               try {
                    con = url .openConnection();
                    // 輸入流
                  InputStream is = con .getInputStream();
                  // 1K的數據緩衝
                  byte [] bs = new byte [1024];
                  // 讀取到的數據長度
                  int len ;
                  // 輸出的文件流
                  OutputStream os = new FileOutputStream( filePath );
                  // 開始讀取
                  while (( len = is .read( bs )) != -1) {
                    os .write( bs , 0, len );
                  }
                  // 完畢,關閉全部連接
                  os .close();
                  is .close();
                  return true ;
              } catch (IOException e ) {
                    // TODO Auto-generated catch block
                    e .printStackTrace();
                    return false ;
              }
             
          } catch (MalformedURLException e ) {
               // TODO Auto-generated catch block
               e .printStackTrace();
               return false ;
          }
       
     }  
相關文章
相關標籤/搜索