How does the singleton mode solve the access_token global cache problem?

小云云
Release: 2023-03-21 08:50:02
Original
3036 people have browsed it

Initially put the access_token in the database, and determine whether it has expired each time it is obtained. It can solve the problem of validity period and number of visits of access_token. However, recently it is necessary to interface the official account with the system and cancel the database of the official account. At this time, it is not appropriate to put access_token, etc. into the system database.

Benefited from this article by Xue Xilin: WeChat handles the issue of access_token global cache, implemented Use singleton mode to cache access_token.

#Remember it for future reference.


#Mark your code structure:

public class TokenSingleton {
        //缓存accessToken 的Map  ,map中包含 一个accessToken 和 缓存的时间戳
         private Map<String, String> map = new HashMap<>();
         private TokenSingleton() {
         }
         private static TokenSi
ngleton single = null;
         // 静态工厂方法
         public static TokenSingleton getInstance() {
             if (single == null) {
                 single = new TokenSingleton();
             }
             return single;
         }
 
         public Map<String, String> getMap() {
             String time = map.get("time");
             String accessToken = map.get("access_token");
             Long nowDate = new Date().getTime();
             
             if (accessToken != null && time != null && nowDate - Long.parseLong(time) < 6000*1000) {
                 System.out.println("accessToken存在,且没有超时 , 返回单例");
             } else {
                 System.out.println("accessToken 超时 , 或者不存在 , 重新获取");
                 String access_token=JSSDKUtil.getAccessToken();
                 //这里是直接调用微信的API去直接获取 accessToken 和Jsapi_ticket 获取
                 String jsapi_token = JSSDKUtil.getTicket(access_token);
                 //"获取jsapi_token";
                 map.put("time", nowDate + "");
                 map.put("access_token", access_token);
                 map.put("jsapi_token", jsapi_token);
             }
             return map;
         }
         public void setMap(Map<String, String> map) {
             this.map = map;
         }
         public static TokenSingleton getSingle() {
             return single;
         }
         public static void setSingle(TokenSingleton single) {
             TokenSingleton.single = single;
         }

 }
Copy after login

Another tool class JSSDKUtil.java intercepted part:
##

public static String getSignature(String accessToken,String jsapi_ticket,String noncestr,String timestamp,String url){
          
        System.out.println("accessToken:"+accessToken+"\njsapi_ticket:"+jsapi_ticket+"\n时间戳:"+timestamp+"\n随机字符串:"+noncestr+"\nURL:"+url);  
        //5、将参数排序并拼接字符串  
        String str = "jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;  
         
        //6、将字符串进行sha1加密  
        String signature =SHA1(str);  
        System.out.println("参数:"+str+"\n签名:"+signature); 
        return signature;
    }
    
    public static String getAccessToken() {  
        String wx_appid = getProperties("wx_appid");
        String wx_appsecret = getProperties("wx_appsecret");
        String access_token = "";  
        String grant_type = "client_credential";//获取access_token填写client_credential   
        String AppId=wx_appid;//第三方用户唯一凭证  
        String secret=wx_appsecret;//第三方用户唯一凭证密钥,即appsecret   
        //这个url链接地址和参数皆不能变  
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type="+grant_type+"&appid="+AppId+"&secret="+secret;  
           
        try {  
            URL urlGet = new URL(url);  
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();  
            http.setRequestMethod("GET"); // 必须是get方式请求  
            http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");  
            http.setDoOutput(true);  
            http.setDoInput(true);  
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒  
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒  
            http.connect();  
            InputStream is = http.getInputStream();  
            int size = is.available();  
            byte[] jsonBytes = new byte[size];  
            is.read(jsonBytes);  
            String message = new String(jsonBytes, "UTF-8");  
            JSONObject demoJson = JSONObject.fromObject(message);  
            System.out.println("JSON字符串:"+demoJson);  
            access_token = demoJson.getString("access_token");  
            is.close();  
        } catch (Exception e) {  
                e.printStackTrace();  
        }  
        return access_token;  
    }  
    public static String getTicket(String access_token) {  
        String ticket = null;  
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token +"&type=jsapi";//这个url链接和参数不能变  
        try {  
            URL urlGet = new URL(url);  
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();  
            http.setRequestMethod("GET"); // 必须是get方式请求  
            http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");  
            http.setDoOutput(true);  
            http.setDoInput(true);  
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒  
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒  
            http.connect();  
            InputStream is = http.getInputStream();  
            int size = is.available();  
            byte[] jsonBytes = new byte[size];  
            is.read(jsonBytes);  
            String message = new String(jsonBytes, "UTF-8");  
            JSONObject demoJson = JSONObject.fromObject(message);  
            System.out.println("JSON字符串:"+demoJson);  
            ticket = demoJson.getString("ticket");  
            is.close();  
        } catch (Exception e) {  
                e.printStackTrace();  
        }  
        return ticket;  
    }  
    public static String SHA1(String decript) {  
        try {  
            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");  
            digest.update(decript.getBytes());  
            byte messageDigest[] = digest.digest();  
            // Create Hex String  
            StringBuffer hexString = new StringBuffer();  
            // 字节数组转换为 十六进制 数  
                for (int i = 0; i < messageDigest.length; i++) {  
                    String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);  
                    if (shaHex.length() < 2) {  
                        hexString.append(0);  
                    }  
                    hexString.append(shaHex);  
                }  
                return hexString.toString();  
       
            } catch (NoSuchAlgorithmException e) {  
                e.printStackTrace();  
            }  
            return "";  
    }
Copy after login
Related recommendations :

A brief analysis of the usage instructions of MySQL memory (global cache + thread cache)_MySQL

The above is the detailed content of How does the singleton mode solve the access_token global cache problem?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!