1. 什么是access_token?

为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台 开放了许多接口,包括自定义菜单接口、客服接口、获取用户信息接口、用户分组接口、群发接口等,

开发者在调用这些接口时,都需要传入一个相同的参数 access_token,它是公众账号的全局唯一票据,它是接口访问凭证。

access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的 access_token失效。

所以获取并缓存access_token是很关键的

2. 封装token类

package com.qjx.weixin.pojo;

public class Token {

	// 接口访问凭证
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;
}
}

3. 如何获取access_token

  1. 通过浏览器公众号网页端输入自己的appid和密码获得

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

这里面的APPID,APPSECRET都替换成自己的私有id和密码就能返回正确的值了

  1. 后台模拟https访问,获取token

https要求我们必须有证书管理器,也就是要实现X509TrustManager接口

我们定义一个MyX509TrustManager类,就直接实现了接口就好了,不用写别的逻辑之类的

接着进行测试,写一个测试类TokenTest,让微信服务器给我们返回一个正确的access_token

可能会遇到没有加入白名单,接收不到的情况,这个只需要把它报错的ip添加进入白名单就可以了

  1. 获取到的token是一个json字符串,将他转化成为对象,需要导入json包,json-lib-2.4-jdk13.jar

封装一个通用的工具类 CommonUtil ,用于专门获取token:

package com.qjx.weixin.util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.qjx.weixin.pojo.Token; import net.sf.json.JSONException;
import net.sf.json.JSONObject; public class CommonUtil { private static Logger log = LoggerFactory.getLogger(CommonUtil.class); // 凭证获取(GET)
public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; /**
* 发送https请求
*
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf); conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod); // 当outputStr不为null时向输出流写数据
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
// 注意编码格式
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
} // 从输入流读取返回内容
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
} // 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
log.error("连接超时:{}", ce);
} catch (Exception e) {
log.error("https请求异常:{}", e);
}
return jsonObject;
} /**
* 获取接口访问凭证
*
* @param appid 凭证
* @param appsecret 密钥
* @return
*/
public static Token getToken(String appid, String appsecret) {
Token token = null;
String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
// 发起GET请求获取凭证
JSONObject jsonObject = httpsRequest(requestUrl, "GET", null); if (null != jsonObject) {
try {
token = new Token();
token.setAccessToken(jsonObject.getString("access_token"));
token.setExpiresIn(jsonObject.getInt("expires_in"));
} catch (JSONException e) {
token = null;
// 获取token失败
log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
}
return token;
} }

4. 将获取到的token缓存起来

  1. 使用缓存框架(redis)

  2. 使用数据库(mysql)

介绍存入数据库的操作

  1. 导入jar包,新建一个数据库配置文件db.properties,在mysql中创建数据库,然后写入db.properties

新建一个jdbc的连接工具类DBUtil,写一个测试类,用于测试是否可以连接数据库

  1. 创建一个保存、读取数据库的token的类TokenUtil,新建一个测试类,看看能不能插入数据和读取数据

  2. 让保存操作每隔7200秒(2小时)就执行一次,

具体思路:Web服务器启动时就加载一个Servlet,在Servlet的init()方法中启动一个线 程,在线程的run()方法中通过死循环+Thread.sleep()的方式定期获取access_token,然后将获取

到的 access_token保存在public static修饰的变量中。

创建一个初始化Servlet类InitServlet,并配置web.xml,使刚加载servlet时就能够获取自己的id和secret,并获取token,创建一个thread类,线程TokenThread定时获取ccess_token。

微信公众号的搭建-第四天(2)-获取并缓存access_token的更多相关文章

  1. C#微信公众号开发系列教程四(接收普通消息)

    微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...

  2. Azure 项目构建 - 用 Azure 认知服务在微信公众号上搭建智能会务系统

    通过完整流程详细介绍了如何在Azure平台上快速搭建基于微信公众号的智慧云会务管理系统. 此系列的全部课程 https://school.azure.cn/curriculums/11 立即访问htt ...

  3. 微信公众号第三方平台生成自定义菜单提示 获取"access_token失败"

    在微信公众号第三方平台要生成自定义菜单时,程序反应很慢,最终提示"获取access_token失败"(之前程序无改动,使用时间已久),查了大半天,找不出原因. 排除.在微信公众号平 ...

  4. C#微信公众号开发之网页授权oauth2.0获取用户基本信息(一)

    咨询 请加 QQ::QQ群: 在微信里面,非认证的公众号账号,只能通过在微信回复菜单单击等事件获取openid,但是认证的公众账号(之前认证的订阅号是不可以的,现在新开放了政府媒体机构的认证订阅号)可 ...

  5. 获取微信公众号的粉丝openid以及用openid获取unionID

    第一步获取微信粉丝的openid https://api.weixin.qq.com/cgi-bin/user/get?access_token=access_token access_token这里 ...

  6. java微信公众号开发----搭建ngrok环境

    下载ngrok,一个能够在公网安全访问内网Web主机的工具 下载地址:http://download.csdn.net/download/u014252425/9389847,亲测可用 下载完成后,进 ...

  7. 用java开发微信公众号:公众号接入和access_token管理(二)

    本文为原创,原始地址为http://www.cnblogs.com/fengzheng/p/5027630.html 上一篇说了微信开发的准备工作,准备工作完成之后,就要开始步入正题了.其实微信公众号 ...

  8. C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件)

    微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...

  9. C#微信公众号开发系列教程五(接收事件推送与消息排重)

    微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...

随机推荐

  1. 经典图算法Java代码实践:BFS,DFS以及几种最短路径算法

    public class City { String name; int id; static int idCounter = 0; public City(String name) { this.n ...

  2. UVa 11997 K Smallest Sums 优先队列&&打有序表&&归并

    UVA - 11997 id=18702" target="_blank" style="color:blue; text-decoration:none&qu ...

  3. 李洪强iOS开发之OC语言前期准备

    OC语言前期准备 一.OC简介 Oc语言在c语言的基础上,增加了一层最小的面向对象语法,完全兼容C语言,在OC代码中,可以混用c,甚至是c++代码. 可以使用OC开发mac osx平台和ios平台的应 ...

  4. C 调用 lua 函数

    C 调用 lua 函数 需要考虑的问题: 1. 使用 lua_pcall 可以调用 lua 函数,首先把 lua 函数入栈,然后把参数入栈, lua_pcall(luaState, 参数个数, 返回值 ...

  5. linq基础,正则表达式,.net相关

    声明扩展方法的步骤:类必须是static,方法是static,第一个参数是被扩展的对象,前面标注this.使用扩展方法的时候必须保证扩展方法类已经在当前代码中using.  LINQ:将int数组中大 ...

  6. java代码格式化

    Java source formatting You are probably familiar with the Eclipse hotkeys to automatically format yo ...

  7. 设计模式中类的关系之关联关系(Association)

    关联关系是类与类之间最常用的一种关系,它是一种结构化关系,用于表示一类对象与另一类对象之间有联系.它体现的是两个类.或者类与接口之间语义级别的一种强依赖关系,比如我和我的朋友.这种关系比依赖更强.不存 ...

  8. Java正则表达式之Matcher类的find和matches方法的区别

    讨论整个问题之前,先看个例子:   从上面的例子可以看出 matches()是整个字符串完全匹配时,才会返回true 而find()则只需要字符串中,找到某部分的子字符串匹配则返回true       ...

  9. 一步一步解析H.264码流的NALU(SPS,PSS,IDR)获取宽高和帧率

    分析H.264码流的工具 CodecVisa,StreamEye以及VM Analyzer NALU是由NALU头和RBSP数据组成,而RBSP可能是SPS,PPS,Slice或SEI 而且SPS位于 ...

  10. 第一百八十一节,jQuery-UI,知问前端--自动补全 UI--邮箱自动补全

    jQuery-UI,知问前端--自动补全 UI--邮箱自动补全 学习要点: 1.调用 autocomplete()方法 2.修改 autocomplete()样式 3.autocomplete()方法 ...