zoukankan      html  css  js  c++  java
  • 玩玩微信公众号Java版之三:access_token及存储access_token

    微信官方参考文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183

     
    基本说明:
    access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
     
    调用方式:
    公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得(需要已经成为开发者,且帐号没有异常状态)。调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。
     
    特别说明:建议公众号开发者使用中控服务器统一获取和刷新Access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务;
     
    了解这些信息后,我们需要理解确定如下几点:
    1、统一token调用方法,其他地方需用到token均采用本方法获取;
    2、请求获取token信息接口的实现;
    3、token数据存储至本地数据库;
    4、判断是否需要重新获取token还是直接从本地数据库中查询;
     
    下面来进行具体的实现:
    首先看一下整体的类图:
     

    那么在获取token时,可以根据appid和appsecret来获取,其中判断是否需要更新的方法为:

    能否获取到当前仍有效的token:查询SQL如下:
     

    对应表结构参考如下:

    对应的java代码如下: 如果能获取到,那么直接返回: 

     1     /**
     2      * 通过参数获取Token信息
     3      * @param appID
     4      * @param appSceret
     5      * @return
     6      */
     7     public Token getToken(String appID, String appSceret)
     8     {
     9         mAppID = appID;
    10         mAppSceret = appSceret;
    11 
    12         // 1.确定是否要更新token,无需更新则直接直接返回获取的token
    13         if (updateToken())
    14         {
    15             return mToken;
    16         }
    17 
    18         // 2. 如需更新
    19         if (!getTokenbyhttps(mAppID, mAppSceret))
    20         {
    21             System.out.println("获取失败!");
    22             return null;
    23         }
    24 
    25         return mToken;
    26     }
    View Code

     其中明细方法实现为:

     1     /**
     2      * 获取Token信息
     3      * @return
     4      */
     5     private boolean updateToken()
     6     {
     7         // 查询数据库数据,如果有则不用更新,无则需要更新
     8         Connection con = null;
     9         PreparedStatement stmt = null;
    10         ResultSet rs = null;
    11         // 判断当前token是否在有效时间内
    12         String sql = " select * from token where appid ='" + mAppID + "' and appsecret ='" + mAppSceret
    13                 + "' and ( current_timestamp -createtime) <expires_in order by createTime desc limit 0,1";
    14         try
    15         {
    16             // 创建数据库链接
    17             con = DBConnPool.getConnection();
    18             // 创建处理器
    19             stmt = con.prepareStatement(sql);
    20             // 查询Token,读取1条记录
    21             rs = stmt.executeQuery();
    22             if (rs.next())
    23             {
    24                 mToken.setTokenid(rs.getString("tokenid"));
    25                 mToken.setToken(rs.getString("token"));
    26                 mToken.setExpires_in(rs.getInt("expires_in"));
    27                 mToken.setAppid(rs.getString("appid"));
    28                 mToken.setAppsecret(rs.getString("appsecret"));
    29             }
    30             else
    31             {
    32                 System.out.println("未查询到对应token");
    33                 return false;
    34             }
    35         }
    36         catch (Exception e)
    37         {
    38             // TODO: handle exception
    39             return false;
    40         }
    41 
    42         System.out.println(mToken.getToken());
    43 
    44         return true;
    45     }
    View Code

    如果需要获取新的token,则:
     1     /**
     2      * 通过https请求获取token
     3      * @param appID
     4      * @param appSceret
     5      * @return
     6      */
     7     private boolean getTokenbyhttps(String appID, String appSceret)
     8     {
     9         String current_time = new Date().getTime() + "";
    10 
    11         try
    12         {
    13             // 请求地址
    14             String path = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
    15                     + appID + "&secret=" + appSceret;
    16             
    17             String strResp = WeChatUtil.doHttpsGet(path, "");
    18             System.out.println(strResp);
    19             
    20             // 解析获取的token信息
    21             Map<String, Object> tMap = WeChatUtil.jsonToMap(strResp);
    22 
    23             System.out.println(tMap.toString());
    24 
    25             mToken.setTokenid(WeChatUtil.getMaxTokenID());
    26             mToken.setToken((String) tMap.get("access_token"));
    27             mToken.setExpires_in(Integer.parseInt((String) tMap.get("expires_in")));
    28             mToken.setAppid(appID);
    29             mToken.setAppsecret(appSceret);
    30             mToken.setCreatetime(current_time);
    31 
    32             System.out.println(mToken.getToken());
    33 
    34         }
    35         catch (HttpException e)
    36         {
    37             // TODO Auto-generated catch block
    38             e.printStackTrace();
    39         }
    40         catch (IOException e)
    41         {
    42             // TODO Auto-generated catch block
    43             e.printStackTrace();
    44         }
    45 
    46         // 存储token至数据库
    47         saveToken(mToken);
    48 
    49         return true;
    50     }
    51 
    52     /**
    53      * 保存Token信息
    54      * @return
    55      */
    56     private boolean saveToken(Token token)
    57     {
    58         PreparedStatement pst = null;
    59         Connection conn = null;
    60         try
    61         {
    62             Token tToken = token.clone();
    63 
    64             System.out.println(tToken.getTokenid() + tToken.getToken());
    65 
    66             conn = DBConnPool.getConnection();
    67             // 创建预处理器
    68             pst = conn.prepareStatement("insert into token(tokenid, token, expires_in,appid, appsecret,createtime) values (?,?,?,?,?,?)");
    69 
    70             pst.setString(1, tToken.getTokenid());
    71             pst.setString(2, tToken.getToken());
    72             pst.setInt(3, tToken.getExpires_in());
    73             pst.setString(4, tToken.getAppid());
    74             pst.setString(5, tToken.getAppsecret());
    75             long now = new Date().getTime();
    76             pst.setTimestamp(6, new java.sql.Timestamp(now));
    77             pst.execute();
    78 
    79         }
    80         catch (CloneNotSupportedException e)
    81         {
    82             // TODO Auto-generated catch block
    83             e.printStackTrace();
    84             return false;
    85         }
    86         catch (SQLException e)
    87         {
    88             // TODO Auto-generated catch block
    89             e.printStackTrace();
    90             return false;
    91         }
    92         catch (Exception e)
    93         {
    94             // TODO: handle exception
    95             System.out.println("出现额外异常");
    96         }
    97         return true;
    98     }
    View Code

    对于https的GET和POST调用,可以写2个公共方法,具体实现可参考:

     1     /**
     2      * HTTPS请求Get方法调用
     3      * @param path
     4      * @param requestData
     5      * @return
     6      * @throws HttpException
     7      * @throws IOException
     8      */
     9     public static String doHttpsGet(String path, String requestData) throws HttpException, IOException
    10     {
    11         // 创建https请求,未默认证书,可自行添加
    12         // 设置编码
    13         HttpClient httpClient = new HttpClient();
    14         GetMethod getMethod = new GetMethod(path);
    15         httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
    16 
    17         httpClient.executeMethod(getMethod);
    18 
    19         // 读取内容
    20         byte[] responseBody = getMethod.getResponseBody();
    21         String strResp = new String(responseBody, "UTF-8");
    22 
    23         System.out.println(strResp);
    24 
    25         getMethod.releaseConnection();
    26 
    27         return strResp;
    28     }
    29 
    30     /**
    31      * HTTPS请求Post方法调用
    32      * @param path
    33      * @param requestData
    34      * @return
    35      * @throws HttpException
    36      * @throws IOException
    37      */
    38     public static String doHttpsPost(String path, String requestData) throws HttpException, IOException
    39     {
    40         // 创建https请求,未默认证书,可自行添加
    41         String strResp ="";
    42         HttpClient httpClient = new HttpClient();
    43         PostMethod postMethod = new PostMethod(path);
    44         // 设置编码
    45         httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
    46         
    47         System.out.println("path:" + path);
    48         System.out.println("requestData:" + requestData);
    49 
    50         postMethod.setRequestBody(requestData);
    51 
    52         long start = System.currentTimeMillis();
    53         // 执行getMethod
    54         int statusCode = httpClient.executeMethod(postMethod);
    55         System.out.println("cost:" + (System.currentTimeMillis() - start));
    56         // 失败
    57         if (statusCode != HttpStatus.SC_OK)
    58         {
    59             System.out.println("Method failed: " + postMethod.getStatusLine());
    60             // 读取内容
    61             byte[] responseBody = postMethod.getResponseBody();
    62             // 处理内容
    63             strResp = new String(responseBody, "UTF-8");
    64             System.out.println(strResp);
    65         }
    66         else
    67         {
    68             // 读取内容
    69             byte[] responseBody = postMethod.getResponseBody();
    70             strResp = new String(responseBody, "UTF-8");
    71             System.out.println("服务器返回:" + strResp);
    72         }
    73 
    74         postMethod.releaseConnection();
    75 
    76         return strResp;
    77     }
    View Code
    需要加入返回是json,处理json 需要json对应的jar,另外需要用到httpclient 的jar包。
    获取token后,要进行数据存储,再返回即可。
     
    获取access_token 这里就结束了,后面的功能接口均需要用到 access_token,这里写的获取方法后面可以直接调用,很方便了哟~
  • 相关阅读:
    JeecgBoot 2.4 微服务正式版发布,基于SpringBoot的低代码平台
    JeecgBoot 常见问题Q&A
    docker安装rabbitmq延时队列插件
    docker安装nacos
    docker安装xxl-job-admin
    docker安装rabbitmq
    低代码开发平台有哪些?
    对比 jeecgboot 和国内外其它低代码平台的区别
    JimuReport积木报表 — API数据源报表带参制作
    JimuReport积木报表 — API数据源报表制作
  • 原文地址:https://www.cnblogs.com/cooldamon/p/7208681.html
Copyright © 2011-2022 走看看