1. 程式人生 > >微信獲取AccessToken以及選單的操作

微信獲取AccessToken以及選單的操作

過了兩三天開始寫微信的第二個博文,最近有點瘋狂,將近兩天的時間寫了快20篇博文,以後要將缺失的博文補回來。好了,開始說微信獲取AccessToken以及選單的操作。

獲取AccessToken的原因很簡單,因為呼叫微信的介面都需要AccessToken,每天獲取accessToken的次數是一定的,而且accessToken有過期時間,本人通過java實現的,需要用到的框架有retrofit(網路請求框架),我會將此框架的程式碼塊放在博文中,現在不在此博文中詳細說明retrofit的使用,以後會陸續寫關於retrofit的博文。

 

首先需要引用retrofit的maven依賴:


<dependency>
	<groupId>com.google.code.gson</groupId>
	<artifactId>gson</artifactId>
</dependency>
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
	<groupId>ch.qos.logback</groupId>
	<artifactId>logback-classic</artifactId>
</dependency>
<!--ArrayUtils 等基礎jar-->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-lang3</artifactId>
	<version>3.4</version>
</dependency>
<!-- commons-io,FileUtils -->
<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.2</version>
</dependency>

<dependency>
	<groupId>com.squareup.okhttp3</groupId>
	<artifactId>okhttp</artifactId>
	<version>3.8.1</version>
</dependency>
<dependency>
	<groupId>com.squareup.okhttp3</groupId>
	<artifactId>logging-interceptor</artifactId>
	<version>3.8.1</version>
</dependency>
<dependency>
	<groupId>com.squareup.retrofit2</groupId>
	<artifactId>retrofit</artifactId>
	<version>2.3.0</version>
</dependency>
<!--json解析-->
<dependency>
	<groupId>com.squareup.retrofit2</groupId>
	<artifactId>converter-gson</artifactId>
	<version>2.3.0</version>
</dependency>
<!--xml解析-->
<dependency>
	<groupId>com.squareup.retrofit2</groupId>
	<artifactId>converter-simplexml</artifactId>
	<version>2.3.0</version>
</dependency>
<dependency>
	<groupId>com.squareup.retrofit2</groupId>
	<artifactId>adapter-rxjava</artifactId>
	<version>2.3.0</version>
</dependency>
<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpclient</artifactId>
	<version>4.5.2</version>
</dependency>

<dependency>
	<groupId>net.sf.json-lib</groupId>
	<artifactId>json-lib</artifactId>
	<version>2.4</version>
	<classifier>jdk15</classifier>
</dependency>

 

封裝retrofit,注意的是,此出使用的是https請求(這個我弄了好久才搞出來 = =)。

package com.xichuan.wechat.common.http;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import javax.net.ssl.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;


/**
 * Created by XiChuan 2018-06-11.
 */
public class HttpClient {
    private static Logger logger = LoggerFactory.getLogger(HttpClient.class);
    public static final HttpClient INSTANCE = new HttpClient();


    /**
     * 獲取HTTPS
     * @param clazz
     * @param host
     * @param <T>
     * @return
     */
    public <T> T getHttpsClient(Class<T> clazz,String host) {
        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor((String s) -> {
        });
        logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        SSLSocketFactory sslSocketFactory = trustAllHosts();
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(logInterceptor)
                .sslSocketFactory(sslSocketFactory)
                .hostnameVerifier((String, SSLSession) -> {
                    //logger.debug("ssl hostname verifier with host: {}", host);
                    return true;
                }).build();

        Retrofit retrofitUser = new Retrofit.Builder()
                .baseUrl(host)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        return retrofitUser.create(clazz);

    }

    /**(因為呼叫第三方網站無法得到證書),信任所有的HTTPS連線*/
    private static SSLSocketFactory trustAllHosts() {
        SSLSocketFactory sslSocketFactory = null;
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                    }

                    public void checkClientTrusted(X509Certificate[] chain,
                                                   String authType) throws CertificateException {
                    }
                    public void checkServerTrusted(X509Certificate[] chain,
                                                   String authType) throws CertificateException {
                    }
                }
        };

        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            sslSocketFactory = sc.getSocketFactory();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return sslSocketFactory;
    }
}

 

定義微信請求介面。

package com.xichuan.wechat.wx.api;

import com.xichuan.wechat.common.http.HttpClient;
import net.sf.json.JSONObject;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;

/**
 * Created by XiChuan 2018-09-26.
 */
public interface WXDevApis {

    /**1.獲取accessToken*/
    @GET("/cgi-bin/token")
    Call<Object> getAccessToken(@Query("grant_type")String grantType,
                                @Query("appid")String appId,
                                @Query("secret")String secret);

    /**2.建立選單*/
    @POST("/cgi-bin/menu/create")
    Call<Object> createMenu(@Query("access_token")String accessToken,
                            @Body JSONObject json);

    /**3.獲取選單*/
    @GET("/cgi-bin/menu/get")
    Call<Object> getMenu(@Query("access_token")String accessToken);

    /**4.刪除選單*/
    @GET("/cgi-bin/menu/delete")
    Call<Object> deleteMenu(@Query("access_token")String accessToken);

    class builder{
        private static String url = "https://api.weixin.qq.com";
        public static WXDevApis getWXDevApis(){
            return HttpClient.INSTANCE.getHttpsClient(WXDevApis.class,url);
        }
    }
}

 

一.獲取accessToken

注意修改程式碼中的appid與secret,這個兩個引數是在你微信公眾號後臺裡面的。

public class WXTest {
    private static final String APPID = "wx111112121219";
    private static final String SECRET = "2eweqe12222222221211111";
    private static Gson gson = new Gson();

    public static void main(String[] args)throws IOException{
        getAccessToken();
    }

    /**1.獲取accessToken*/
    public static void getAccessToken()throws IOException{
        Response<Object> response =
                WXDevApis.builder.getWXDevApis().getAccessToken("client_credential", APPID, SECRET).execute();

        if (response.isSuccessful()){
            AccessToken accessToken = gson.fromJson( gson.toJson(response.body()), AccessToken.class);

            if (StringUtils.isBlank(accessToken.access_token)){
                System.out.println("get access token error!,"+gson.toJson(response.body()));
            }else{
                System.out.println(accessToken.access_token );
            }
        }else{
            System.out.println("request error");
        }
    }
}

二.建立選單

建立選單,微信介面文件中已經給出每個欄位的含義了,在此分下一下建立選單的程式碼。

微信建立選單json引數說明

引數	   是否必須	               說明
button	         是	                        一級選單陣列,個數應為1~3個
sub_button	 否	                        二級選單陣列,個數應為1~5個
type	         是	                        選單的響應動作型別,view表示網頁型別,click表示點選型別,miniprogram表示小程式型別
name	         是	                        選單標題,不超過16個位元組,子選單不超過60個位元組
key	       click等點選型別必須	        選單KEY值,用於訊息介面推送,不超過128位元組
url            view、miniprogram型別必須          網頁 連結,使用者點選選單可開啟連結,不超過1024位元組。 type為miniprogram時,不支援小程式的老版本客戶端將開啟本url。
media_id       media_id型別和view_limited型別必須	呼叫新增永久素材介面返回的合法media_id
appid	       miniprogram型別必須	        小程式的appid(僅認證公眾號可配置)
pagepath       miniprogram型別必須	        小程式的頁面路徑

建立選單程式碼:

package com.xichuan.wechat.wx.api;

import com.google.gson.Gson;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import retrofit2.Response;

import java.io.IOException;

/**
 * Created by XiChuan on 2018-09-26.
 */
public class WXTest {
    private static Gson gson = new Gson();
    private static String ACCESS_TOKEN = "15_0Lv0-A6NqWq-ob8W8ufelVhwHI-SaihRYCi9Ph4I949P0QKH1aQPl3x2Fsjudc84uW9BhA3fAik1qWr2mxubQPUaQDBX3Xvlj5BXp4N69AuRU9uKTJwjBsvSbup-CXoarJu_q-HbNfk6gZr7VXRjAHAQSM1";

    public static void main(String[] args)throws IOException{
        createMenu();
   
    }

    /**3.建立選單*/
    public static void createMenu()throws IOException{
        //一級選單
        JSONArray menuBtnArray = new JSONArray();

        //一級按鈕button1
        JSONObject menuBtn1 = new JSONObject();
        menuBtn1.put("type","view");
        menuBtn1.put("name","百度");
        menuBtn1.put("url","http://www.baidu.com");
        menuBtnArray.add(menuBtn1);

        //一級按鈕button2
        JSONObject menuBtn2 = new JSONObject();
        menuBtn2.put("name","父選單");
        menuBtn2.put("key","V1001_btn3");

        //二級選單->menuBtn2
        JSONArray menuBtn2Array = new JSONArray();

        //二級按鈕Button1
        JSONObject menuBtn2Sub1 = new JSONObject();
        menuBtn2Sub1.put("type","view");
        menuBtn2Sub1.put("name","百度");
        menuBtn2Sub1.put("url","http://www.baidu.com");
        menuBtn2Array.add(menuBtn2Sub1);

        //二級按鈕Button2
        JSONObject menuBtn2Sub2 = new JSONObject();
        menuBtn2Sub2.put("type","view");
        menuBtn2Sub2.put("name","搜狗");
        menuBtn2Sub2.put("url","http://www.sogou.com");
        menuBtn2Array.add(menuBtn2Sub2);
        menuBtn2.put("sub_button",menuBtn2Array);

        menuBtnArray.add(menuBtn2);

        JSONObject button = new JSONObject();
        button.put("button",menuBtnArray);
        System.out.println(button.toString());

        Response<Object> response =
                WXDevApis.builder.getWXDevApis().createMenu(ACCESS_TOKEN,button).execute();
        if (response.isSuccessful()){

            System.out.println(gson.toJson(response.body()));

        }else{
            System.out.println("request error");
        }
    }
}

建立選單時,生產的json:

{
	"button": [{
		"type": "view",
		"name": "百度",
		"url": "http://www.baidu.com"
	}, {
		"name": "父選單",
		"key": "V1001_btn3",
		"sub_button": [{
			"type": "view",
			"name": "百度",
			"url": "http://www.baidu.com"
		}, {
			"type": "view",
			"name": "搜狗",
			"url": "http://www.sogou.com"
		}]
	}]
}

三.獲取選單

package com.xichuan.wechat.wx.api;

import com.google.gson.Gson;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import retrofit2.Response;

import java.io.IOException;

/**
 * Created by XiChuan 2018-09-26.
 */
public class WXTest {
    private static Gson gson = new Gson();

    private static String ACCESS_TOKEN = "15_0Lv0-A6NqWq-ob8W8ufelVhwHI-SaihRYCi9Ph4I949P0QKH1aQPl3x2Fsjudc84uW9BhA3fAik1qWr2mxubQPUaQDBX3Xvlj5BXp4N69AuRU9uKTJwjBsvSbup-CXoarJu_q-HbNfk6gZr7VXRjAHAQSM1";

    public static void main(String[] args)throws IOException{
        getMenu();
    }

    /**3.獲取選單*/
    public static void getMenu()throws IOException{
        Response<Object> response =
                WXDevApis.builder.getWXDevApis().getMenu(ACCESS_TOKEN).execute();
        if (response.isSuccessful()){
            System.out.println(gson.toJson(response.body()));
        }else{
            System.out.println("request error");
        }
    }
}

四.刪除選單

package com.xichuan.wechat.wx.api;

import com.google.gson.Gson;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import retrofit2.Response;

import java.io.IOException;

/**
 * Created by XiChuan on 2018-09-26.
 */
public class WXTest {
    private static Gson gson = new Gson();

    private static String ACCESS_TOKEN = "15_0Lv0-A6NqWq-ob8W8ufelVhwHI-SaihRYCi9Ph4I949P0QKH1aQPl3x2Fsjudc84uW9BhA3fAik1qWr2mxubQPUaQDBX3Xvlj5BXp4N69AuRU9uKTJwjBsvSbup-CXoarJu_q-HbNfk6gZr7VXRjAHAQSM1";

    public static void main(String[] args)throws IOException{
        deleteMenu();
    }

    /**3.刪除選單*/
    public static void deleteMenu()throws IOException{
        Response<Object> response =
                WXDevApis.builder.getWXDevApis().deleteMenu(ACCESS_TOKEN).execute();
        if (response.isSuccessful()){
            System.out.println(gson.toJson(response.body()));
        }else{
            System.out.println("request error");
        }
    }
}

對於會retrofit的同學來說,上面的程式碼應該很簡單,因為就是呼叫微信提供的介面而已,但不會retrofit的同學,建議學習學習,這個網路請求框架比原生態的httpClient請求方便的多的多。好了,本部落格就到這裡吧。