微信接口调用凭证access_token的管理

access_token 是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

1、为了保密appsecrect,第三方需要一个access_token获取和刷新的中控服务器。而其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则会造成access_token覆盖而影响业务;

2、目前access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器对外输出的依然是老access_token,此时公众平台后台会保证在刷新短时间内,新老access_token都可用,这保证了第三方业务的平滑过渡;

3、access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程。

http请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

下面介绍的方法并非使用中控服务器更新token,而是通过一个默认启动的servlet,启动一个进程,该进程会不停的请求微信接口获取token,若获取成功,就会休眠7000秒。

代码:

token实体类
AccessToken .java

package com.sh.po;

public class AccessToken { 

      private String accessToken; 
      private int expiresin;

      public String getAccessToken() { 
        return accessToken; 
      } 

      public void setAccessToken(String accessToken) { 
        this.accessToken = accessToken; 
      } 

      public int getExpiresin() { 
        return expiresin; 
      } 

      public void setExpiresin(int expiresin) { 
        this.expiresin = expiresin; 
      } 

    }

默认启动的servlet
AccessTokenServlet.java

package com.sh.sevlet;

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import com.sh.util.TokenThread;
import java.io.IOException; 

/**
 * 定义一个默认启动的servlet,在init方法中启动一个Thread,这个进程中定义一个无限循环的方法,用来获取access_token,
 * 当获取成功后,此进程休眠7000秒,否则休眠3秒钟继续获取
 * @author Administrator
 *
 */
public class AccessTokenServlet extends HttpServlet { 

  public void init() throws ServletException { 
    //获取servlet初始参数appid和appsecret(参数在web.xml配置),并赋值给TokenThread对应的静态全局变量。 
    //TokenThread.appId和TokenThread.appSecret是静态的
    TokenThread.appId = getInitParameter("appid"); 
    TokenThread.appSecret = getInitParameter("appsecret"); 
    System.out.println("appid:"+TokenThread.appId); 
    System.out.println("appSecret:"+TokenThread.appSecret); 
    new Thread(new TokenThread()).start(); //启动进程 
  } 

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

  } 

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

  } 
}

web.xml配置

 <servlet>
    <servlet-name>AccessTokenServletservlet-name>
    <servlet-class>com.sh.sevlet.AccessTokenServletservlet-class>
    <init-param>
      <param-name>appidparam-name>
      <param-value>APPIDparam-value>
    init-param>
    <init-param>
      <param-name>appsecretparam-name>
      <param-value>APPSECRETparam-value>
    init-param>
    <load-on-startup>0load-on-startup>
  servlet>

  <servlet-mapping>
    <servlet-name>AccessTokenServletservlet-name>
    <url-pattern>/accesstokenservleturl-pattern>
  servlet-mapping>

获取access_token的进程类

package com.sh.util;

import org.json.JSONObject;
import com.sh.po.AccessToken;
/**
 * 定义Thread类,在此类中调用access_token获取接口,并将得到的数据抽象到静态实体,以便在其它地方使用
 * @author Administrator
 *
 */
public class TokenThread implements Runnable { 
  public static String appId = ""; 
  public static String appSecret= ""; 
  //注意是静态的,可以全局存储访问。
  public static AccessToken accessToken = null; 

  public void run(){ 
    while (true){ 
      try{ 
        accessToken = this.getAccessToken(); //调用getAccessToken获取access_token
        if(null!=accessToken){ 
          System.out.println(accessToken.getAccessToken()); 
          Thread.sleep(7000 * 1000); //获取到access_token 休眠7000秒  
        }else{ 
          Thread.sleep(1000*3); //access_token为空 休眠3秒 
        } 
      }catch(Exception e){ 
        System.out.println("发生异常:"+e.getMessage()); 
        e.printStackTrace(); 
        try{ 
          Thread.sleep(1000*10); //发生异常休眠1秒 
        }catch (Exception e1){ 

        } 
      } 
    } 
  } 

  /** 
   * 获取access_token 
   * @return 
   */
  private AccessToken getAccessToken(){ 
    //微信jssdk获取jsapi_ticket时获取access_tokend的请求路径 https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
    //此处获取的access_token和网页授权时获取的access_token的不同
    String jsticket = "";
        try {
            jsticket = Http.methodGet("https://api.weixin.qq.com/cgi-bin/token","grant_type=client_credential&appid="+this.appId+"&secret="+this.appSecret+"");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    JSONObject ticket = new JSONObject(jsticket);
    AccessToken token = new AccessToken(); 
    token.setAccessToken(ticket.getString("access_token")); 
    return token; 
  } 
}

在poster.java的使用

        String jstoken = TokenThread.accessToken.getAccessToken();

你可能感兴趣的:(Java,微信开发)