In order to enable third-party developers to provide users with more valuable personalized services, the WeChat public platform has opened many interfaces, including custom menu interfaces, customer service interfaces, user information acquisition interfaces, user grouping interfaces, and group sending interfaces, etc. When developers call these interfaces, they need to pass in the same parameter access_token, which is the globally unique ticket of the public account and is the interface access credential.
The validity period of access_token is 7200 seconds (two hours). During the validity period, it can be used continuously. Only when the access_token expires, you need to call the interface again to obtain the access_token. Under ideal circumstances, a system running 7x24 hours only needs to obtain access_token 12 times a day, that is, once every 2 hours. If the access_token is obtained again within the validity period, the access_token obtained last time will be invalid.
Currently, the call frequency of the get access_token interface is limited to 2000 times/day. If every time you send a customer service message, obtain user information, or send a group message, you must first call the get access_token interface to obtain the interface access credentials. This is obviously Unreasonable. On the one hand, it will be more time-consuming (one more interface call operation). On the other hand, the 2000 call limit per day may not be enough. Therefore, in practical applications, we need to store the obtained access_token, and then regularly call the access_token interface to update it to ensure that the access_token taken out at any time is valid.
The following will introduce how to obtain and store access_token regularly. Please note: This is not an article explaining how to call the interface to obtain access_token. For information on obtaining access_token, please refer to the article "WeChat Public Account Development Tutorial Part 14 - Custom Menu Creation and Menu Event Response".
Let’s do a brief analysis before taking action. What we have to solve is nothing more than the following two problems:
1. How to obtain access_token regularly?
In Java, if you want to execute a task regularly, you need to use the java.util.Timer class. For those who like to use frameworks, you can use the open source task scheduling framework quartz. The Spring framework also supports quartz. In addition, another method is to start a thread, write an infinite loop in the thread's run() method, and then use Thread.sleep() to ensure that the thread executes a certain task regularly.
2. Where to save access_token?
For the storage of access_token, you can consider storing it in a file, database or memory. The specific storage method used needs to be determined according to the actual situation of the project. If there is only one server, storing access_token directly in memory is the simplest and most effective way.
In this article, the author will demonstrate the process of regularly obtaining and storing access_token as follows: loading a Servlet when the Web server starts, starting a thread in the Servlet's init() method, and in the thread's run() In the method, access_token is obtained regularly through an infinite loop + Thread.sleep(), and then the obtained access_token is saved in a variable modified by public static.
Create an InitServlet class in the project. The code of this class is as follows:
package org.liufeng.weixin.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import org.liufeng.weixin.thread.TokenThread; import org.liufeng.weixin.util.WeixinUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 初始化servlet * * @author liuyq * @date 2013-05-02 */ public class InitServlet extends HttpServlet { private static final long serialVersionUID = 1L; private static Logger log = LoggerFactory.getLogger(WeixinUtil.class); public void init() throws ServletException { // 获取web.xml中配置的参数 TokenThread.appid = getInitParameter("appid"); TokenThread.appsecret = getInitParameter("appsecret"); log.info("weixin api appid:{}", TokenThread.appid); log.info("weixin api appsecret:{}", TokenThread.appsecret); // 未配置appid、appsecret时给出提示 if ("".equals(TokenThread.appid) || "".equals(TokenThread.appsecret)) { log.error("appid and appsecret configuration error, please check carefully."); } else { // 启动定时获取access_token的线程 new Thread(new TokenThread()).start(); } } }
As can be seen from the above code, the InitServlet class only rewrites the init() method and does not rewrite it. doGet() and doPost() methods, because we do not intend to let InitServlet handle access requests. The implementation of the init() method is also relatively simple. First obtain the parameters appid and appsecret configured in web.xml, and then start the thread TokenThread to obtain the access_token regularly.
The configuration of InitServlet in web.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee <a href="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" "="">http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"</a>> <servlet> <servlet-name>initServlet</servlet-name> <servlet-class> org.liufeng.weixin.servlet.InitServlet </servlet-class> <!-- 配置获取access_token所需参数appid和appsecret --> <init-param> <param-name>appid</param-name> <param-value>wx617a123bb8bc99cd</param-value> </init-param> <init-param> <param-name>appsecret</param-name> <param-value>4d82cbbbb08714c12345b62d7hn3dcb8</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
The configuration of InitServlet in web.xml is different from the configuration of ordinary Servlet in several points: 1) By configuring
The source code of TokenThread is as follows:
package org.liufeng.weixin.thread; import org.liufeng.weixin.pojo.AccessToken; import org.liufeng.weixin.util.WeixinUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 定时获取微信access_token的线程 * * @author liuyq * @date 2013-05-02 */ public class TokenThread implements Runnable { private static Logger log = LoggerFactory.getLogger(TokenThread.class); // 第三方用户唯一凭证 public static String appid = ""; // 第三方用户唯一凭证密钥 public static String appsecret = ""; public static AccessToken accessToken = null; public void run() { while (true) { try { accessToken = WeixinUtil.getAccessToken(appid, appsecret); if (null != accessToken) { log.info("获取access_token成功,有效时长{}秒 token:{}", accessToken.getExpiresIn(), accessToken.getToken()); // 休眠7000秒 Thread.sleep((accessToken.getExpiresIn() - 200) * 1000); } else { // 如果access_token为null,60秒后再获取 Thread.sleep(60 * 1000); } } catch (InterruptedException e) { try { Thread.sleep(60 * 1000); } catch (InterruptedException e1) { log.error("{}", e1); } log.error("{}", e); } } } }
Line 23 of the code constructs an infinite loop (permanent execution) through while(true){}; Line 25 calls the public The platform interface obtains the access_token; line 29 lets the thread sleep for 7000 seconds before running, that is, the access_token is obtained every 7000 seconds to ensure that the access_token never expires. In other classes in the project, you can get the interface access credential access_token by calling TokenThread.accessToken.getToken(). Deploy and run the program locally. After Tomcat is started, the following log will be displayed on the console:
[INFO ] weixin api appid:wx617a123bb8bc99cd [INFO ] weixin api appsecret:4d82cbbbb08714c12345b62d7hn3dcb8 [INFO ] 获取access_token成功,有效时长7200秒 token:sFopJ9lMmLl4u-ad61ojKpS0TolhN2s3SnHoI2Mh5GgdiYb35i-7DG2T2CDyQKMe
In order to visually see the effect of regularly obtaining access_token, you can try to modify the thread sleep time in TokenThread to 30 seconds or 60 seconds.
The above is the detailed content of WeChat public platform development method to ensure long-term validity of access_token. For more information, please follow other related articles on the PHP Chinese website!