微信官方参考文档: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. }

其中明细方法实现为:

  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. }

如果需要获取新的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. }

对于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. }
需要加入返回是json,处理json 需要json对应的jar,另外需要用到httpclient 的jar包。
获取token后,要进行数据存储,再返回即可。
 
获取access_token 这里就结束了,后面的功能接口均需要用到 access_token,这里写的获取方法后面可以直接调用,很方便了哟~

玩玩微信公众号Java版之三:access_token及存储access_token的更多相关文章

  1. 玩玩微信公众号Java版之七:自定义微信分享

    前面已经学会了微信网页授权,现在微信网页的功能也可以开展起来啦! 首先,我们先来学习一下分享,如何在自己的页面获取分享接口及让小伙伴来分享呢? 今天的主人公: 微信 JS-SDK, 对应官方链接为:微 ...

  2. 玩玩微信公众号Java版之四:自定义公众号菜单

    序: 微信公众号基本的菜单很难满足个性化及多功能的实现,那么微信能否实现自定菜单呢,具体的功能又如何去实现么?下面就来学习一下微信自定义公众号菜单吧! 自定义菜单接口可实现多种类型按钮,如下: 1.c ...

  3. 玩玩微信公众号Java版之一:配置微信公众平台服务器信息

    在进行微信公众平台开发前,前先做好准备工作,好了以后,我们可以开始啦!   第一.准备好服务端接口   定义一个http服务接口,主要分为如下几步:   1.创建一个servlet类,用来接收请求: ...

  4. 玩玩微信公众号Java版之准备

    微信自2013年流行起来,现在的发展已经超过了我们的想象,那么对应的公众平台,小程序等都是让人眼前一亮的东西,这里来学习一下微信工作号的对接,实现为Java,希望大家一起学习!   这里大概描述一下所 ...

  5. 玩玩微信公众号Java版之六:微信网页授权

    我们经常会访问一些网站,用微信登录的时候需要用到授权,那么微信网页授权是怎么一回事呢,一起来看看吧!   参考官方文档:https://mp.weixin.qq.com/wiki?t=resource ...

  6. 玩玩微信公众号Java版之五:获取关注用户信息

    在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同).公众号可通过本接口来根据Op ...

  7. 玩玩微信公众号Java版之二:接收、处理及返回微信消息

    前面已经配置了微信服务器,那么先开始最简单的接收微信消息吧~   可以用我们的微信号来直接进行测试,下面先看测试效果图:   这是最基本的文本消息的接收.处理及返回,来看看是怎么实现的吧!   首先可 ...

  8. 微信公众号Java接入demo

    微信公众号Java接入demo 前不久买了一台服务,本来是用来当梯子用的,后来买了一个域名搭了一个博客网站,后来不怎么在上面写博客一直闲着,最近申请了一个微信公众号就想着弄点什么玩玩.周末没事就鼓捣了 ...

  9. 微信公众平台Java版极速SDK

    JEEWX-API 是第一个微信公众平台Java版极速SDK,基于 jeewx-api 开发可以立即拥有简单易用的API,让开发更加轻松自如,节省更多时间 http://www.jeewx.com/

随机推荐

  1. NodeJs的简单介绍

    Nodejs是由谷歌v8运行.c++编写的js运行的环境,这里需要记住的是Nodejs只是一个环境.  目前很多主流网站都是使用nodejs,如知乎等大型的网站. 我们关于nodejs学习目标:安装N ...

  2. SpringBoot学习helloworld

    这几天开始学习springBoot记录一下(Hello World) pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0 ...

  3. 搭建rtmp直播流服务之2:使用java实现ffmpeg命令接口化调用(用java执行ffmpeg命令)

    欢迎大家积极开心的加入讨论群 群号:371249677 (点击这里进群) 一.环境搭建 1.安装ffmpeg 下载对应系统的ffmpeg安装包,个人采用windows平台进行开发,所以安装了windo ...

  4. git clone https://github.com/istester/ido.git ,确提示“Failed to connect to 192.168.1.22 port 8080: Connection refused” 的解决办法 。

    不知道是否有同学遇到如下的问题: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo } span.s1 { } git clone ...

  5. python 标准库 -- multiprocessing

    multiprocessing 与 threading.Thread 类似 multiprocessing.Process 创建进程, 该进程可以运行用 python 编写的函数. multiproc ...

  6. 深入理解 JavaScript 事件循环(二)— task and microtask

    引言 microtask 这一名词是 JS 中比较新的概念,几乎所有人都是在学习 ES6 的 Promise 时才接触这一新概念,我也不例外.当我刚开始学习 Promise 的时候,对其中回调函数的执 ...

  7. Java学习笔记--反射API

    反射API 1.反射API的介绍 通过反射API可以获取Java程序在运行时刻的内部结构.比如Java类中包含的构造方法.域和方法等元素,并可以与这些元素进行交换.     按照 一般地面向对象的设计 ...

  8. Python读取和处理文件后缀为".sqlite"的数据文件

    最近在弄一个项目分析的时候,看到有一个后缀为”.sqlite”的数据文件,由于以前没怎么接触过,就想着怎么用python来打开并进行数据分析与处理,于是稍微研究了一下. SQLite是一款非常流行的关 ...

  9. PHP中几个输出函数echo,print(),print_r(),sprintf(),var_dump()的区别

    1:echo:是语句不是函数,没有返回值,可输出多个变量值,不需要圆括号.不能输出数组和对象,只能打印简单类型(如int,string). 2:print:是语句不是函数,有返回值 1 ,只能输出一个 ...

  10. 调用phprpc的时候出现Fatal error: Cannot redeclare gzdecode()

    出现这个问题的原因是:php在5.4版本后,已经自包含了gzdecode()函数,开发者自己定义的gzdecode()函数会与其冲突. 在 ....\phpRPC\compat.php文件的第72行( ...