微信开发定时器更新token

本文介绍了一种通过定时器实现微信Token及Ticket定时刷新的方法,确保了Token的有效性,并减少了向微信服务器请求的频率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在做微信开发,网上资料一大堆,但是要在原来的pc代码上修改则需要修改部分代码才能实现两台服务器之间的完美通信,今天写一下关于微信token的更新。

满足条件:token随时能用,本地获取,向微信服务器请求次数不会超过限制。

思路:采用定时器每隔2小时向微信请求一次并把结果保存到数据库中,定时器在系统启动后开始运行。

java代码,tomcat7

监听器代码:

package gbkj.listener;

import gbkj.weixin.util.CommonUtil;
import gbkj.weixin.util.ParamesAPI;

import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.gb.sysmodule.model.base.Ticket;
import com.gb.sysmodule.model.base.Token;
import com.gb.sysmodule.service.SpringUtil;
import com.gb.sysmodule.service.base.TicketServiceI;
import com.gb.sysmodule.service.base.TokenServiceI;

/**
 * 后台定时任务:刷新access_token和tickect
 * 
 * @author liuxiong
 *
 */
public class MyContextListener implements ServletContextListener{//xml中声明此监听
	
	private TokenServiceI tokenService;
	private TicketServiceI ticketService;
	
	private ServletContext context = null;//web应用
	private Timer timer = null;
	public  MyContextListener() {
		super();
	}

	/**
	 * 两小时执行一次刷新,考虑网络延迟,实际时间会更短
	 */
	@Override
	public void contextInitialized(ServletContextEvent sce) {
        this.context = sce.getServletContext();//获取当前应用
        timer = new java.util.Timer(true);//相关线程为守护程序
        sce.getServletContext().log("定时器已启动");
        
        long delay1 = 1000;//tomcat启动后1秒开始执行
        long period = 7140000;//每隔1小时59分执行一次
        timer.schedule(new MyTask(this.context), delay1, period);//(任务,延迟,间隔)
        sce.getServletContext().log("已经添加任务调度表");
		
	}
	
	public void getService() {
		if (tokenService==null) {
			tokenService = (TokenServiceI)SpringUtil.getBean("tokenService");
		}
		if (ticketService==null) {
			ticketService = (TicketServiceI)SpringUtil.getBean("ticketService");
		}
		freshToken();
        freshTicket();
	}
	
	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		timer.cancel();
        this.context.log("定时器销毁");
        this.context = null;
	}

	public void freshToken() {
		Token token = CommonUtil.getToken(ParamesAPI.corpId, ParamesAPI.corpsecret);
		if (token!=null) {
			tokenService.saveOrUpdate(token);
			context.log("更新token成功!");
		}else {
			context.log("获取token失败!");
		}
	}
	
	public void freshTicket() {
		Token token = tokenService.getByHql("from Token");
		if (token!=null) {
			Ticket ticket = CommonUtil.getTicket(token);
			if (ticket!=null) {
				ticketService.saveOrUpdate(ticket);
				context.log("更新ticket成功!");
				return;
			}
		}
		context.log("获取ticket失败!");
	}
	
	private class MyTask extends TimerTask {
        private ServletContext context = null;
        public MyTask(ServletContext context) {
            this.context = context;
        }
 
        // 下面的方法会按之前设定的每5秒执行一次,所以,此处不需要循环
        public void run() {
            context.log("开始执行更新任务");
            getService();
            context.log("更新任务执行结束");
        }
    }
	
	
	
	
}
在web.xml加上监听器声明,这样监听器就会在程序启动之后在后台一直运行:

监听器配置:
<listener><!--定时器  -->
        <listener-class>gbkj.listener.MyContextListener</listener-class>
</listener>

### 微信开发者工具 Token 过期解决方案 #### 存储与缓存机制 为了有效管理 `access_token` 的生命周期并减少频繁请求带来的风险,建议采用本地存储和内存缓存相结合的方式。当首次成功获取到有效的 `access_token` 后,将其保存至文件系统或数据库中,并设置相应的过期时间戳以便后续判断其有效性[^1]。 ```python import time from datetime import timedelta def save_access_token(token, expires_in=7200): """保存 access_token 及其有效期""" with open('token_cache.txt', 'w') as f: now = int(time.time()) expire_time = now + expires_in - 60 # 提前一分钟刷新 f.write(f"{expire_time}\n{token}") ``` #### 判断Token 是否已过期 在实际应用过程中,在发起任何依赖于 `access_token` 的 API 请求之前,应该先检查当前持有的令牌是否仍然处于有效期内。如果发现即将到期,则立即重新申请新的令牌来替换旧版本[^3]。 ```python def is_token_expired(): """检测 access_token 是否已经过期""" try: with open('token_cache.txt', 'r') as f: lines = f.readlines() if not lines or len(lines) != 2: return True expire_time_str, _ = map(str.strip, lines) expire_time = int(expire_time_str) current_time = int(time.time()) return current_time >= expire_time except FileNotFoundError: return True ``` #### 自动化更新流程 通过定时器或其他调度方式定期执行上述逻辑,确保即使在网络波动情况下也能及时捕获到接近失效的时间节点从而触发提前续订操作。此外还可以考虑引入重试机制以应对偶尔可能出现的服务不可达状况[^4]。 ```python import schedule import requests def fetch_new_access_token(appid, secret): url = "https://api.weixin.qq.com/cgi-bin/token" params = { "grant_type": "client_credential", "appid": appid, "secret": secret } response = requests.get(url=url,params=params).json() new_token = response['access_token'] expires_in = response.get('expires_in', 7200) save_access_token(new_token, expires_in) if __name__ == "__main__": APPID = "<your_wechat_app_id>" SECRET = "<your_wechat_secret_key>" # 初始化时尝试加载现有 token 或创建新 token if is_token_expired(): fetch_new_access_token(APPID, SECRET) # 设置每小时检查一次 token 状态的任务 schedule.every().hour.do(check_and_refresh_if_needed) while True: schedule.run_pending() time.sleep(1) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值