微信官方参考文档: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 /**View Code
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 /**View Code 如果需要获取新的token,则:
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 }
1 /**View Code
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 /**View Code
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,这里写的获取方法后面可以直接调用,很方便了哟~