1. 程式人生 > >Java 華為推送 Access Token過期重新整理

Java 華為推送 Access Token過期重新整理

相信大家都遇到過這樣的需求,就是整合各種各樣的推送通道,信鴿、小米、華為等等。今天我就來說說我在整合華為推送過程中遇到的小坑------Access Token過期問題。
//標註1
//樣例中的程式碼(Demo.class.getResource("/mykeystorebj.jks").openStream(), "123456");
InputStream inputStream = new FileInputStream("/data" + storeJks);
OAuth2Client oauth2Client = new OAuth2Client();
oauth2Client.initKeyStoreStream(inputStream, "xxxxxx"
); AccessToken access_token = oauth2Client.getAccessToken("client_credentials", appId, appKey); //標註2 logger.info("access token :" + access_token.getAccess_token() + ",expires time[access token 過期時間]:" + access_token.getExpires_in()); client = new NSPClient(access_token.getAccess_token()); //設定每個路由的連線數和最大連線數
client.initHttpConnections(30, 50); InputStream inputStreamO = new FileInputStream("/data" + storeJks); //如果訪問https必須匯入證書流和密碼 client.initKeyStoreStream(inputStreamO, "xxxxxx");

第一坑:
詳見上面這段程式碼中的標註1,經多次測試,根本無法得到類路徑下的mykeystorebj.jks檔案,故改成了在伺服器中指定路徑的方式,一次就過了。

第二坑:
詳見上面這段程式碼中的標註2,在呼叫OAuth2返回的Access Token後,會伴隨這返回這個Access Token的過期時間,固定為七天,這裡很坑爹,只有在有效期結束前自己手動重新整理才可以,否則client將無法正常使用,我這裡就是利用guava包中的cache來解決重新整理Access Token的問題。

package com.huawei;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import nsp.NSPClient;
import nsp.OAuth2Client;
import nsp.support.common.AccessToken;
import nsp.support.common.NSPException;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

public class HuaWeiApp {

    private static final Logger logger = LoggerFactory.getLogger(HuaWeiApp.class);
    public static final String TIMESTAMP_NORMAL = "yyyy-MM-dd HH:mm:ss";

    private NSPClient client;
    private String appId;
    private String appKey;
    private String storeJks;

    //我這裡選擇了每六天一重新整理
    private Cache<String, NSPClient> cache = CacheBuilder.newBuilder().expireAfterWrite(518400, TimeUnit.SECONDS).build();

    private NSPClient getClient() throws Exception {

        cache.get("client", new Callable<NSPClient>() {
            @Override
            public NSPClient call() throws Exception {
                    InputStream inputStream = new FileInputStream("/data" + storeJks);
                    OAuth2Client oauth2Client = new OAuth2Client(); 
                    oauth2Client.initKeyStoreStream(inputStream, "xxxxxx");

                    logger.info("access token :" + access_token.getAccess_token() + ",expires time[access token 過期時間]:" + access_token.getExpires_in());

                    client = new NSPClient(access_token.getAccess_token());
                    //設定每個路由的連線數和最大連線數
                    client.initHttpConnections(30, 50);

                    //如果訪問https必須匯入證書流和密碼
                    InputStream inputStreamO = new FileInputStream("/data" + storeJks);

                    return client;
            }
        });
        return client;

    }
}

這裡我利用cache來定期重新整理Access Token,首先我設定重新整理週期為每六天,其次我利用cache的get方法獲取client,如果沒有獲取到,則會重新執行重新整理的操作。