微信公眾號-入門的坑

litblank發表於2018-08-21

寫自未接觸過公眾號,也不知道什麼是token的搬運工。

一、需求

要求後臺管理系統生成帶使用者標籤的二維碼,使用者掃碼後獲取引數併為使用者打上標籤,之後微信根據標籤的不同顯示不同的選單

二、技術調研

生成帶引數的二維碼

  • 首先需要獲得access_token,可以根據appid和secret直接呼叫介面直接獲取,但是是新生成的並且是佔用了次數,可以從token管理中獲取一個未失效的token
  • 根據token呼叫獲取所有標籤的介面,獲得標籤id
  • 根據token呼叫獲得二維碼ticket的介面,根據引數設定有效時長和是否有效
  • 根據ticket呼叫檢視二維碼介面

搭建微信認證伺服器

  • git搜尋公眾號demo
  • 修改appid、secret、令牌、金鑰引數
  • 修改開源專案埠為80,使用https://natapp.cn/內網穿透到本地80埠
  • 將穿透的域名認證伺服器的地址填寫到公眾號伺服器地址上
  • 之後就可以愉快的打斷點,隨意調教

三、結果

流程是沒有問題的,能夠實現,只不過標籤對應的自定義選單是在第三方維護的,使用者掃碼後立刻能打上標籤,但是並不能立刻顯示對應的自定義選單,好像很5分鐘獲取一次選單有關。需求不了了之。

四、上線

  • 後續,兩星期之後上線,配置認證伺服器之後,每次獲取的token都是40001,token失效,清除redis儲存的快取之後,獲取的token不到1小時又失效了,檢視了官方文件,原本2小時的有效期,根本不靠譜,隨後又修改token重新整理時間,基本穩定。

四、坑-總結

  • 坑不大,只要看著微信文件就可以知道調什麼介面,搜尋也很方便,比百度好使。文件整理:

獲取使用者資訊標籤文件:mp.weixin.qq.com/wiki?t=reso…

為使用者打標籤介面文件:mp.weixin.qq.com/wiki?t=reso…

關注獲取到引數:mp.weixin.qq.com/wiki?t=reso…

  • token的獲取最好由一個服務提供,還需要配置白名單,不可能每個專案都生成token

  • 推薦入門開源專案:github.com/binarywang/… 專案為weixin-java-tools的Demo演示程式,推薦了內網穿透的使用,而且是springboot專案,基本事件的處理。

  • 更加強大的開源專案:github.com/Wechat-Grou… 內容太多,程式碼優美,學習一下如何構建微信專案。

  • 發起http請求,可以使用apache.http.client、okHttp。貼出apache工具類:若有覺得不怎麼好,可自行百度

徹底入門OkHttp使用 blog.csdn.net/u013651026/…

package com.wechat.web.util;

import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import javax.servlet.ServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
 
public class HttpUtil {
    /**
     *
     * @param url 請求地址
     * @param data 請求資料
     * @return String 響應string
     * @throws Exception 異常
     */
    public static String post(String url, Map<String,String> data) throws Exception{
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);

        if (data != null) {
            List<NameValuePair> nvps = new ArrayList<>();
            data.forEach((key, value) -> {
                nvps.add(new BasicNameValuePair(key, value));
            });
            httpPost.setEntity(new UrlEncodedFormEntity(nvps));
        }
        ResponseHandler<String> responseHandler = getStringResponseHandler();
        return httpClient.execute(httpPost, responseHandler);
    }

    /**
     * @param url  請求地址
     * @param body 請求資料
     * @return responseContent 響應資料
     */
    public static String post(String url, String body) {
        String responseContent = "";
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("Content-Type", "application/json");

            StringEntity s = new StringEntity(body, "utf-8");
            s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
            httpPost.setEntity(s);

//            httpPost.setEntity(new StringEntity(body));

            response = httpClient.execute(httpPost);

            HttpEntity entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, Consts.UTF_8);

        } catch (ParseException | IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return responseContent;
    }

    /**
     *
     * @param url 請求地址
     * @throws Exception todo 是否異常
     */
    public static String get(String url) {
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        ResponseHandler<String> responseHandler = getStringResponseHandler();
        try {
            return httpClient.execute(httpGet, responseHandler);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     *     Create a custom response handler
     */
    private static ResponseHandler<String> getStringResponseHandler() {
        return (final HttpResponse response) -> {
            int status = response.getStatusLine().getStatusCode();
            if (status >= 200 && status < 300) {
                HttpEntity entity = response.getEntity();
                return entity != null ? EntityUtils.toString(entity, Consts.UTF_8) : null;
            } else {
                throw new ClientProtocolException("Unexpected response status: " + status);
            }
        };
    }


    /**
     * 獲取請求Body
     *
     * @param request ServletRequest
     * @return String
     */
    public static String getBodyString(ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }

}

複製程式碼

相關文章