Maison  >  Article  >  développement back-end  >  Comment le mode singleton résout-il le problème du cache global access_token ?

Comment le mode singleton résout-il le problème du cache global access_token ?

小云云
小云云original
2018-03-12 14:01:163041parcourir

Mettez initialement le access_token dans la base de données et déterminez s'il a expiré à chaque fois qu'il est obtenu. Cela peut résoudre le problème de la période de validité et du nombre de visites de access_token. Cependant, récemment, il est nécessaire d'interfacer le compte officiel avec le système et d'annuler la base de données du compte officiel. À l'heure actuelle, il n'est pas approprié de mettre access_token, etc. dans la base de données du système.

Bénéficiez de cet article de Xue Xilin : WeChat gère le problème de mise en cache globale access_token, implémenté Utilisation mode singleton pour mettre en cache access_token.

Mémorisez-le pour référence future.


Marquez la structure de votre code :

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;
         }

 }

Une autre classe d'outils JSSDKUtil.java a intercepté une partie :

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 "";  
    }

Recommandations associées :

Une brève analyse des instructions d'utilisation de la mémoire MySQL (cache global + cache de threads)_MySQL

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn