最近須要將微信的accesstoken保存到緩存裏面,防止重複請求微信接口獲取token,形成token請求次數超標,其實隨便一個緩存均可以輕鬆解決,可是現有的環境中沒有redis,沒有memcahe,作一個這個小功能,不須要引入這些框架,就用guava的過時map就能夠了,不要要是服務宕機了,可又要從新獲取了,這個...再也不考慮範圍內了.java
依賴包:redis
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>20.0</version> </dependency>
Cache這個類有不少,防止導錯,給出包名:apache
import com.alibaba.fastjson.JSON; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.gson.Gson; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils;
聲明全局靜態變量Cachejson
private static Cache<String, String> cache = null;
設置過時時間,通常微信的token過時時間是7200s,我設的短一些:api
/** * 緩存其accessToken 和 ticketToken 的值 * * @param key * @return * @throws Exception */ public static String getTicketToken(String key) throws Exception{ if (Objects.isNull(cache) || getCacheAccessToken(key).equals(WeChatConstant.TICKET_TOKEN)){ Gson gson = new Gson(); cache = CacheBuilder.newBuilder().expireAfterWrite(7100,TimeUnit.SECONDS).build(); String accessToken = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+WeChatConstant.APPID +"&secret="+WeChatConstant.SECRET; String httpResult = getHttpResult(accessToken); log.info("獲取的accesstoken:{}",httpResult); System.out.println("----"+accessToken+"----"); AccessToken aT = gson.fromJson(accessToken, AccessToken.class); String signUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+aT.getAccess_token()+"&type=jsapi"; String resultSign = getHttpResult(signUrl); TicketToken ticket = gson.fromJson(resultSign, TicketToken.class); log.info("生成的ticket:{},值是:{}",ticket,ticket.getTicket()); cache.put(WeChatConstant.TICKET_TOKEN,ticket.getTicket()); log.info("從新生成accessToken:{},{}",accessToken,new Date(System.currentTimeMillis())); return ticket.getTicket(); }else{ return getCacheAccessToken(key); } }
/** * token失效,返回key值 * * @param key * @return * @throws ExecutionException */ private static String getCacheAccessToken(String key) throws ExecutionException { return cache.get(key, () -> { return key; }); } /** * 隨機加密 * @param hash * @return */ private static String byteToHex(final byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", b); } String result = formatter.toString(); formatter.close(); return result; } /** * 獲取訪問地址連接返回值 */ private static String getHttpResult(String url) { String result = ""; HttpGet httpRequest = new HttpGet(url); try { HttpResponse httpResponse = HttpClients.createDefault().execute(httpRequest); if (httpResponse.getStatusLine().getStatusCode() == 200) { result = EntityUtils.toString(httpResponse.getEntity()); } } catch (ClientProtocolException e) { e.printStackTrace(); result = e.getMessage().toString(); } catch (IOException e) { e.printStackTrace(); result = e.getMessage().toString(); } return result; } /** * 產生隨機串--由程序本身隨機產生 * @return */ private static String create_nonce_str() { return UUID.randomUUID().toString(); } /** * 由程序本身獲取當前時間 * @return */ private static String create_timestamp() { return Long.toString(System.currentTimeMillis() / 1000); }
給出兩個json轉換的實體類:緩存
/** * @author zhangyi * @date 2019/2/11 17:19 */ @Data public class AccessToken { private String access_token; private Integer expires_in; }
/** * @author zhangyi * @date 2019/2/11 17:25 */ @Data public class TicketToken { private Integer errcode; private String errmsg; private String ticket; private Integer expires_in; }
常量:微信
/** * 第三方用戶惟一憑證即appsecret */ public static final String SECRET = ""; /** * 第三方用戶惟一憑證密鑰, */ public static final String APPID = ""; /** * 微信access_token */ public static final String ACCESS_TOKEN = "ACCESS_TOKEN"; /** * 微信ticket_token */ public static final String TICKET_TOKEN = "TICKET_TOKEN";
至此完成這個功能就不須要引入框架,直接使用這個工具類就能夠完成了,俗話說:殺雞焉用宰牛刀,哈哈,但願能夠幫到各位app