参考:https://www.cnblogs.com/liuhongfeng/p/4848851.html

一:介绍。

接口调用请求说明

http请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

参数说明

参数 是否必须 说明
grant_type 获取access_token填写client_credential
appid 第三方用户唯一凭证
secret 第三方用户唯一凭证密钥,即appsecret

返回说明

正常情况下,微信会返回下述JSON数据包给公众号:

{"access_token":"ACCESS_TOKEN","expires_in":7200}
参数 说明
access_token 获取到的凭证
expires_in 凭证有效时间,单位:秒

错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):

{"errcode":40013,"errmsg":"invalid appid"}

我们可以直接

二:封装基本类。

package com.wx.bean;

/**
* 封装token类。
*/
public class AccessToken {
//获取到的凭证
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;
}
}

三:如何获取token。

一:直接访问浏览器。替换自己的appid和secret。

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

二:编写程序,模拟https连接,获得token。

对于https请求,我们需要一个证书信任管理器,这个管理器类需要自己定义,但需要实现X509TrustManager接口,

package com.wx.util;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager; /**
* 类名: MyX509TrustManager </br>
* 描述: 信任管理器 </br>
* 开发人员: 六 </br>
* 发布版本:V1.0 </br>
*/
public class MyX509TrustManager implements X509TrustManager { // 检查客户端证书
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
} // 检查服务器端证书
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
} // 返回受信任的X509证书数组
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}

微信服务器返回的是json数据,如何从json里面解析出来的值?所以要转换成Java对象。

封装一个通用的Util。

package com.wx.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 com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.wx.bean.AccessToken; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* 类名: CommonUtil </br>
* 描述: 通用工具类 </br>
* 开发人员: 六 </br>
* 创建时间: 2018-8-9 </br>
* 发布版本:V1.0 </br>
*/
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.parseObject(buffer.toString());
} catch (ConnectException ce) {
log.error("连接超时:{}", ce);
} catch (Exception e) {
log.error("https请求异常:{}", e);
}
return jsonObject;
} /**
* 获取接口访问凭证
*
* @param appid 凭证
* @param appsecret 密钥
* @return
*/
public static AccessToken getToken(String appid, String appsecret) {
AccessToken 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 AccessToken();
token.setAccessToken(jsonObject.getString("access_token"));
token.setExpiresin(jsonObject.getInteger("expires_in"));
} catch (JSONException e) {
token = null;
// 获取token失败
log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
}
}
return token;
}
}

然后写个token的测试类就可以获取到token

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
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 com.wx.bean.AccessToken;
import com.wx.util.CommonUtil;
import com.wx.util.MyX509TrustManager;
import org.junit.Test; public class TokenTest { @Test
public void testGetToken1() throws Exception {
String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxb05f6ccd16cf38fb&secret=b50d2e0911e255f4723f93d73233b04f";
// 建立连接
URL url = new URL(tokenUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); // 创建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(); httpUrlConn.setSSLSocketFactory(ssf);
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true); // 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod("GET"); // 取得输入流
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(
inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
// 读取响应内容
StringBuffer buffer = new StringBuffer();
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
httpUrlConn.disconnect();
// 输出返回结果
System.out.println(buffer);
} @Test
public void testGetToken2() {
AccessToken token = CommonUtil.getToken("appID","appsecret");
System.out.println("access_token:"+token.getAccessToken());
System.out.println("expires_in:"+token.getExpiresin());
}
}

在项目中的其他类,可以通过调用 TokenThread.accessToken.getToken() 来得到接口访问凭证access_token。

四:问题:但是如何让这个保存工作隔7200 秒进行保存呢?

方案:

做一个定时器。

做一个web实现监听器。

定期获取并存储access_token的流程为:

Web服务器启动时就加载一个Servlet,在Servlet的init()方法中启动一个线 程,在线程的run()方法中通过死循环+Thread.sleep()的方式定期获取access_token,然后将获取到的 access_token保存在public static修饰的变量中。

在工程中创建一个InitServlet类,该类的代码如下:

InitServlet类只重写了init()方法,并没有重写doGet()和doPost()两个方法,

因为我们并不打算让 InitServlet来处理访问请求。

package com.wx.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet; import com.wx.util.CommonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* 类名: InitServlet </br>
* 描述: 初始化servlet </br>
* 包:com.wx.servlet</br>
* 开发人员: 六 </br>
* 创建时间: 2018-8-9 </br>
* 发布版本:V1.0 </br>
*/ @WebServlet(
name = "AccessTokenServlet",
urlPatterns = {"/AccessTokenServlet"},
loadOnStartup = 1,
initParams = {
@WebInitParam(name = "appId", value = "wxb05f6ccd16cf38fb"),
@WebInitParam(name = "appSecret", value = "b50d2e0911e255f4723f93d73233b04f")
})
public class InitServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static Logger log = LoggerFactory.getLogger(CommonUtil.class); public void init() throws ServletException {
System.out.println("启动得到Token的Servlet");
// 获取web.xml中配置的参数
TokenThread.appid = getInitParameter("appId");
TokenThread.appsecret = getInitParameter("appSecret"); log.info("weixin api appid:{}", TokenThread.appid);
log.info("weixin api appsecret:{}", TokenThread.appsecret); // 未配置appid、appsecret时给出提示
if ("".equals(TokenThread.appid) || "".equals(TokenThread.appsecret)) {
log.error("appid and appsecret configuration error, please check carefully.");
} else {
// 启动定时获取access_token的线程
new Thread(new TokenThread()).start();
}
}
}
package com.wx.servlet;

import com.wx.bean.AccessToken;
import com.wx.bean.Ttoken;
import com.wx.util.CommonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* 类名: TokenThread </br>
* 描述: 定时获取微信access_token的线程 </br>
* 开发人员: 六 </br>
* 创建时间: 2018-8-9 </br>
* 发布版本:V1.0 </br>
*/
public class TokenThread implements Runnable {
private static Logger log = LoggerFactory.getLogger(TokenThread.class); /* @Autowired
TtokenMapper ttokenMapper;
*/
// 第三方用户唯一凭证
public static String appid = "";
// 第三方用户唯一凭证密钥
public static String appsecret = "";
public static AccessToken accessToken = null; public void run() {
while (true) {
try {
accessToken = CommonUtil.getToken(appid, appsecret);
if (null != accessToken) {
//调用存储到数据库
System.out.println("Token的值:"+accessToken);
Ttoken ttoken = new Ttoken(3,accessToken.getAccessToken(),accessToken.getExpiresin(),null);
System.out.println("Ttoken的值:"+ttoken);
//ttokenMapper.select();
//ttokenMapper.save(ttoken);
log.info("获取access_token成功,有效时长{}秒 token:{}", accessToken.getExpiresin(), accessToken.getAccessToken());
// 休眠7000秒
Thread.sleep((accessToken.getExpiresin() - 200)*1000);
} else {
// 如果access_token为null,60秒后再获取
Thread.sleep(60 * 1000);
}
} catch (InterruptedException e) {
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e1) {
log.error("{}", e1);
}
log.error("{}", e);
}
}
}
}

代码中通过while(true){}构造了一个死循环(永久执行);

调用公众平台接口获取access_token;

让线程休眠7000秒再运行,即每隔7000秒获取一次access_token,保证access_token永不失效。

微信公众号开发(二)获取access_token的更多相关文章

  1. Java微信公众号开发----定时获取access_token并保存到redis中

    本人原本是想做微信公众号菜单的创建修改删除等操作的,但是发现需要access_token,通过阅读文档,发现文档要求有以下几点: 1.access_token 获取后有效期是2小时 2.access_ ...

  2. 微信公众号开发及时获取当前用户Openid及注意事项

    目录 (一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 (四)微信公众号开发之网页授权获取用户基本信息 (五)微信公众号开发之网页中及 ...

  3. 微信公众号开发系列-获取微信OpenID

    在微信开发时候在做消息接口交互的时候须要使用带微信加密ID(OpenId),下面讲讲述2中类型方式获取微信OpenID.接收事件推送方式和网页授权获取用户基本信息方式获取. 1.通过接收被动消息方式获 ...

  4. tp6微信公众号开发者模式获取access_token

    1:config 文件下新建一个文件wechat.php,将个人id和秘钥写入配置文件 网址: https://developers.weixin.qq.com/doc/offiaccount/Bas ...

  5. 微信公众号开发之获取微信用户的openID

    (注:openID同一用户同一应用唯一,UnionID同一用户不同应用唯一.不同应用指微信开放平台下的不同用户.) 1.  申请测试号(获得appID.appsecret) 2.  填写服务器配置并验 ...

  6. 微信公众号开发前端获取openId

    参考 https://blog.csdn.net/qq_35430000/article/details/79299529

  7. 微信公众号开发用户授权登录报"redirect_uri 参数错误"错误

    微信公众号开发 授权获取用户信息报错 "redirect_uri 参数错误" 出现这个情况要检查下 微信公众号配置了网页授权域名 在这里配置微信公众号redirect_uri中的域 ...

  8. C#微信公众号开发-高级接口-之网页授权oauth2.0获取用户基本信息(二)

    C#微信公众号开发之网页授权oauth2.0获取用户基本信息(一) 中讲解了如果通过微信授权2.0snsapi_base获取已经关注用户的基本信息,然而很多情况下我们经常需要获取非关注用户的信息,方法 ...

  9. 微信公众号开发(三)获取access_token

    微信公众号开发(三)获取access_token 1.说明 access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token.开发者需要进行妥善保存.acce ...

  10. 微信公众号开发之网页中及时获取当前用户Openid及注意事项

    目录 (一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 (四)微信公众号开发之网页授权获取用户基本信息 (五)微信公众号开发之网页中及 ...

随机推荐

  1. windows传输文件到linux脚本

    安装pscp https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html cmd脚本 @echo off rem 拷贝的文件名称 se ...

  2. dependencies 和 starter

    以 spring-cloud-alibaba-dependencies-1.5.0.RELEASE 为例: <dependency> <groupId>com.alibaba. ...

  3. 抓包工具tcpdump用法说明--2

    第一招: 通俗的说,tcpdump是一个抓包工具,用于抓取互联网上传输的数据包.形象的说,tcpdump就好比是国家海关,驻扎在出入境的咽喉要道,凡是要入境和出境的集装箱,海关人员总要打开箱子,看看里 ...

  4. 类HashSet

    /* * Collection * * List * 有序(存储顺序和取出顺序一致),可以重复 * * Set * 无序(存储顺序和取出顺序不一致),唯一 * * */ import java.uti ...

  5. Android Studio 连接夜神模拟器

    网上找到的解决是需要我们 然后运行cmd命令,cd到夜神安装目录,执行命令 nox_adb.exe connect 127.0.0.1:62001

  6. HttpModule 介绍

    引言 Http 请求处理流程 和 Http Handler 介绍 这两篇文章里,我们首先了解了Http请求在服务器端的处理流程,随后我们知道Http请求最终会由实现了IHttpHandler接口的类进 ...

  7. 【HANA系列】SAP HANA DB 和SAP HANA studio version查看

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA DB 和SAP ...

  8. promise 封装 axios

    /*axios({ method:"get", url:"./data.json", data:{ id:10 } }).then((res)=>{ co ...

  9. git篇之二----团体项目中使用git

    上篇说了git的简单入门,本篇来说一下在团体项目中我们该如何简单使用git 一般来说,当我们进入公司之后,就前端项目而言,若是有多个同事共同开发一个系统,我们可能会每个人去负责各自的模块. 若是人员较 ...

  10. Python:库文件

    可以引用的Python文件:自己写的.py + 外部库(external libraries)