相信大家都遇到过这样的需求,就是集成各种各样的推送通道,信鸽、小米、华为等等。今天我就来说说我在集成华为推送过程中遇到的小坑------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,如果没有获取到,则会重新执行刷新的操作。