如何保证access_token长期有效--微信公众平台开发(一)

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_33556185/article/details/52758781

        何为access_token?引用微信官方的一定义:access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。微信获取access_token接口每日限制调用2000次,因此我们必须将token保存起来,省着点去获取新的access_token。

最简单的方式就是保存在内存中,此方法适用于单机应用。如果服务是集群或者分布式应用,还是保存在数据库中吧。此例以保存在内存中为例。

1:token过期的时候重新去获取新的token。

2:内存中拿不到token的时候去调用微信接口获取token。

CoreService类:

	/**
	 * 获取微信公众号平台接口的ACCESS_TOKEN
	 * @return
	 */
	public  String getWeixinAccessToken(){
		WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
		ServletContext application = webApplicationContext.getServletContext();
		if(application.getAttribute("tokenMap")!=null){
			WeixinAccessToken tempToken=(WeixinAccessToken) application.getAttribute("tokenMap");
		    if(System.currentTimeMillis()>tempToken.getExpirationTime()){
		    	return tempToken.getAccessToken();
		    }else{
		    	return getAccessToken();
		    }
		}else{
			return getAccessToken();
		}
	}

	private String getAccessToken() {
		WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
		ServletContext application = webApplicationContext.getServletContext();
		String appId=appid;
		String appSecret=secret;
		String url="https://api.weixin.qq.com/cgi-bin/token";
		String returnData=Common.sendGet(url,"grant_type=client_credential&appid="+appId+"&secret="+appSecret);
		JSONObject json=JSONObject.fromObject(returnData);
		if(json.containsKey("access_token")){
			if(json.get("access_token")!=null&&!json.get("access_token").equals("")){
				application.setAttribute("tokenMap", new WeixinAccessToken(json.get("access_token").toString(),
						System.currentTimeMillis()+Integer.parseInt(json.get("expires_in").toString())));
				return json.get("access_token").toString();
			}
		}
		return null;
	}

上面的实现麻烦了些,还有另外一种方式是将access_token存在redis,利用redis的过期策略来维护access_token的有效期。

实现如下:

	/**
	 * 获取access_token
	 * @return
	 */
	private String getAccessToken(){
		//从缓存里去获取token
		String weixinAccessToken=JedisUtil.get("weixinAccessToken");
		if(StringUtil.isBlank(weixinAccessToken)){
			 String appId=appid;  
			 String appSecret=secret;  
			 String url="https://api.weixin.qq.com/cgi-bin/token";  
			 String returnData=HttpUtil.sendGet(url,"grant_type=client_credential&appid="+appId+"&secret="+appSecret);  
			 JSONObject json=JSONObject.fromObject(returnData);  
			 if(json.containsKey("access_token")){  
			     if(json.get("access_token")!=null&&!json.get("access_token").equals("")){  
			         weixinAccessToken=json.get("access_token").toString(); 
			         JedisUtil.set("weixinAccessToken",weixinAccessToken, 7200);
			     }  
			 }  
		}
		return weixinAccessToken;
	}

WeixinAccessToken类:

public class WeixinAccessToken {
	private String accessToken;
	private long expirationTime;
	
	public WeixinAccessToken(){
		
	}

   public WeixinAccessToken(String accessToken,long expirationTime){
	  this.accessToken=accessToken;
	  this.expirationTime=expirationTime;
	}

      public String getAccessToken() {
		return accessToken;
	}
	public void setAccessToken(String accessToken) {
		this.accessToken = accessToken;
	}
	public long getExpirationTime() {
		return expirationTime;
	}
	public void setExpirationTime(long expirationTime) {
		this.expirationTime = expirationTime;
	}
	

}

发送get请求和post请求工具类HttpUtil:

/**
     * 向指定URL发送GET方法的请求
     * @param url 发送请求的URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }

	/**
	 * 发送post请求
	 */
	public static String sendPost(String url, String param) {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			// 设置通用的请求属性
			conn.setConnectTimeout(30000);
			conn.setRequestProperty("Accept", "*/*");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			out.print(param);
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			System.out.println("发送 POST 请求出现异常!" + e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输出流、输入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	}


展开阅读全文

没有更多推荐了,返回首页