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. atitit.MIZIAN 陕北方言 特有词汇 大词典 attilax 整理 h--n v1 q31.xlsx

    atitit.MIZIAN 陕北方言 特有词汇 大词典 attilax 整理 h--n v1 q31.xlsx 1  Mizian陕北方言 english英语 spain西班牙语 cantonese粤 ...

  2. redhat samba安装配置

    突然想要用,好久没配过这玩意了,再次配置一次,记录一下过程. 1.挂载镜像      mount -o loop ~/Desktop/RHEL_5.5\ i386\ DV.iso /mnt       ...

  3. css之常用属性

    背景属性: background-attachment 设置背景图像是否固定或者随着页面的其余部分滚动 值: scroll 默认值.背景图像会随着页面其余部分的滚动而移动. fixed 当页面的其余部 ...

  4. codeblocks中给GCC编译器加参数

    在使用gcc命令行编译的时候可以使用gcc xxx.c -o xxx.exe -std=c99来使用c99标准编译 但是在codeblocks中默认是不使用c99标准编译的,如何加参数呢? Setti ...

  5. 如何修改SESSION的生存时间

    php中session过期时间设置网上很多人给出了解答:修改php配置文件中的session.gc_maxlifetime.如果想了解更多session回收机制,继续阅读.(本文环境php5.2) 概 ...

  6. hdu 1106 水

    背景:简单字符串处理,尽管有点绕. #include<cstdio> #include<iostream> #include<cstring> #include&l ...

  7. CentOS上使用Squid+Stunnel搭建代理服务器教程

    这篇文章主要介绍了CentOS上使用Squid+Stunnel搭建代理服务器教程,同时文中也介绍了用户认证的方法,适合于多用户共同使用代理,这种功能在国内用还是比较exciting的~需要的朋友可以参 ...

  8. easyUI combox静态动态联动

    easyUI重写了select,取而代之的是combobox,有如下几种方式可以创建一个combobox 1.使用select标签,并加上class="easyui-combobox&quo ...

  9. 用Flex实现常见的几种布局

    用Flex实现常见的几种布局 1.水平,垂直居中. <style type="text/css"> .container{ display: flex; width: ...

  10. day8笔记

    一.上节回顾 1,id() 内存地址2, == 比较的是值 is 比较的是内存地址 数字,字符串,有小数据池, #内存地址一样的 int -5--256 str:1,不能有空格. 2,长度不能超过20 ...