微信官方参考文档: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代码如下: 如果能获取到,那么直接返回:

     /**
* 通过参数获取Token信息
* @param appID
* @param appSceret
* @return
*/
public Token getToken(String appID, String appSceret)
{
mAppID = appID;
mAppSceret = appSceret; // 1.确定是否要更新token,无需更新则直接直接返回获取的token
if (updateToken())
{
return mToken;
} // 2. 如需更新
if (!getTokenbyhttps(mAppID, mAppSceret))
{
System.out.println("获取失败!");
return null;
} return mToken;
}

其中明细方法实现为:

     /**
* 获取Token信息
* @return
*/
private boolean updateToken()
{
// 查询数据库数据,如果有则不用更新,无则需要更新
Connection con = null;
PreparedStatement stmt = null;
ResultSet rs = null;
// 判断当前token是否在有效时间内
String sql = " select * from token where appid ='" + mAppID + "' and appsecret ='" + mAppSceret
+ "' and ( current_timestamp -createtime) <expires_in order by createTime desc limit 0,1";
try
{
// 创建数据库链接
con = DBConnPool.getConnection();
// 创建处理器
stmt = con.prepareStatement(sql);
// 查询Token,读取1条记录
rs = stmt.executeQuery();
if (rs.next())
{
mToken.setTokenid(rs.getString("tokenid"));
mToken.setToken(rs.getString("token"));
mToken.setExpires_in(rs.getInt("expires_in"));
mToken.setAppid(rs.getString("appid"));
mToken.setAppsecret(rs.getString("appsecret"));
}
else
{
System.out.println("未查询到对应token");
return false;
}
}
catch (Exception e)
{
// TODO: handle exception
return false;
} System.out.println(mToken.getToken()); return true;
}

如果需要获取新的token,则:
     /**
* 通过https请求获取token
* @param appID
* @param appSceret
* @return
*/
private boolean getTokenbyhttps(String appID, String appSceret)
{
String current_time = new Date().getTime() + ""; try
{
// 请求地址
String path = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
+ appID + "&secret=" + appSceret; String strResp = WeChatUtil.doHttpsGet(path, "");
System.out.println(strResp); // 解析获取的token信息
Map<String, Object> tMap = WeChatUtil.jsonToMap(strResp); System.out.println(tMap.toString()); mToken.setTokenid(WeChatUtil.getMaxTokenID());
mToken.setToken((String) tMap.get("access_token"));
mToken.setExpires_in(Integer.parseInt((String) tMap.get("expires_in")));
mToken.setAppid(appID);
mToken.setAppsecret(appSceret);
mToken.setCreatetime(current_time); System.out.println(mToken.getToken()); }
catch (HttpException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} // 存储token至数据库
saveToken(mToken); return true;
} /**
* 保存Token信息
* @return
*/
private boolean saveToken(Token token)
{
PreparedStatement pst = null;
Connection conn = null;
try
{
Token tToken = token.clone(); System.out.println(tToken.getTokenid() + tToken.getToken()); conn = DBConnPool.getConnection();
// 创建预处理器
pst = conn.prepareStatement("insert into token(tokenid, token, expires_in,appid, appsecret,createtime) values (?,?,?,?,?,?)"); pst.setString(1, tToken.getTokenid());
pst.setString(2, tToken.getToken());
pst.setInt(3, tToken.getExpires_in());
pst.setString(4, tToken.getAppid());
pst.setString(5, tToken.getAppsecret());
long now = new Date().getTime();
pst.setTimestamp(6, new java.sql.Timestamp(now));
pst.execute(); }
catch (CloneNotSupportedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
catch (SQLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
catch (Exception e)
{
// TODO: handle exception
System.out.println("出现额外异常");
}
return true;
}

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

     /**
* HTTPS请求Get方法调用
* @param path
* @param requestData
* @return
* @throws HttpException
* @throws IOException
*/
public static String doHttpsGet(String path, String requestData) throws HttpException, IOException
{
// 创建https请求,未默认证书,可自行添加
// 设置编码
HttpClient httpClient = new HttpClient();
GetMethod getMethod = new GetMethod(path);
httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8"); httpClient.executeMethod(getMethod); // 读取内容
byte[] responseBody = getMethod.getResponseBody();
String strResp = new String(responseBody, "UTF-8"); System.out.println(strResp); getMethod.releaseConnection(); return strResp;
} /**
* HTTPS请求Post方法调用
* @param path
* @param requestData
* @return
* @throws HttpException
* @throws IOException
*/
public static String doHttpsPost(String path, String requestData) throws HttpException, IOException
{
// 创建https请求,未默认证书,可自行添加
String strResp ="";
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(path);
// 设置编码
httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8"); System.out.println("path:" + path);
System.out.println("requestData:" + requestData); postMethod.setRequestBody(requestData); long start = System.currentTimeMillis();
// 执行getMethod
int statusCode = httpClient.executeMethod(postMethod);
System.out.println("cost:" + (System.currentTimeMillis() - start));
// 失败
if (statusCode != HttpStatus.SC_OK)
{
System.out.println("Method failed: " + postMethod.getStatusLine());
// 读取内容
byte[] responseBody = postMethod.getResponseBody();
// 处理内容
strResp = new String(responseBody, "UTF-8");
System.out.println(strResp);
}
else
{
// 读取内容
byte[] responseBody = postMethod.getResponseBody();
strResp = new String(responseBody, "UTF-8");
System.out.println("服务器返回:" + strResp);
} postMethod.releaseConnection(); return strResp;
}
需要加入返回是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. 一位菜鸟的java 最基础笔记

    java的特性 简单性(Simple). 结构体系中立(Architecture Neutral). 面向对象(Object Oriented). 易于移植(Portable). 分布式(Distri ...

  2. Java之戳中痛点 - (7)善用Java整型缓存池

    先看一段代码: package com.test; import java.util.Scanner; public class IntegerCache { public static void m ...

  3. Facebook开源Zstandard新型压缩算法代替Zlib 简单使用

    简介 Zstandard(缩写为Zstd)是由Facebook的Yann Collet开发的一个无损数据压缩算法.Zstandard在设计上与DEFLATE(.zip.gzip)算法有着差不多的压缩比 ...

  4. 小试牛刀JavaScript鼠标事件

    鼠标事件练习1 当鼠标点击网页某个单元格的时候,其他的单元格颜色不变,只有被点击的单元格颜色发生变化 <style type="text/css"> *{ margin ...

  5. 框架篇:Spring+SpringMVC+Mybatis整合开发

    前言: 前面我已搭建过ssh框架(http://www.cnblogs.com/xrog/p/6359706.html),然而mybatis表示不服啊. Mybatis:"我抗议!" ...

  6. JavaScript练习笔记整理·3 - 6.25

    欢迎和大家一起来讨论~   基础练习(1):   我的解答为: function array_diff(a, b) { if (b == "") return a; return ...

  7. sql求和isnull注意事项

    如果不用isnull函数判断则计算出来如果有一列是null 则相加就是null,如 两列:1 null 1+null = nullselect sum(ISNULL(jinE,0)+ISNULL(qi ...

  8. web开发中前后端传值

    在JavaScript中,页面与页面间的传值需要注意. 比如,我们通过url向下个页面进行传一个数字时,到下个页面进行解析出来后可能是一个字符串.这样会导致一个现象.调试时,发现我要传的值的确传过来了 ...

  9. 淘宝tairKV分布式

    Tair是什么 Tair是由淘宝开发的key/value方案,系统默认支持基于内存和文件的存储引擎,对应于通常我们所说的缓存和持久化存储,这里可以获取更多关于tair的信息,淘宝团队介绍,Tair在淘 ...

  10. ECMAScript 6 中的快捷语法汇总及代码示例

    对于每个 JavaScript 开发人员,快捷语法都是必备技能之一,下面就集中介绍这些快捷语法. 三元运算符 传统写法 const x = 20; let answer; if (x > 10) ...