Java微信公众号开发----定时获取access_token并保存到redis中
本人原本是想做微信公众号菜单的创建修改删除等操作的,但是发现需要access_token,通过阅读文档,发现文档要求有以下几点:
1.access_token 获取后有效期是2小时
2.access_token 占用512个字符空间
3.获取access_token 的url 为(get请求) : https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
4.请求成功返回的格式为:{"access_token":"ACCESS_TOKEN","expires_in":7200}
思路:
1.前提必须是成功获取到 access_token
2. 项目里需要配置一个定时器,用来定期获取 access_token
3.成功获取后应该把access_token妥善保存,比如保存在 数据库、缓存(本人所选,redis)、配置文件中都可以
步骤一:获取access_token
- package com.encore.util;
- import org.json.JSONObject;
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.util.List;
- import java.util.Map;
- public class WeChatTokenUtil {
- //获取access_token的url
- private static final String BASE_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?";
- //固定值
- private static final String GRANT_TYPE = "client_credential";
- //自己的AppID
- private static final String APP_ID = "**********";
- //自己的AppSecret
- private static final String SECRET = "***********";
- public static String getToken(){
- String url = BASE_TOKEN_URL + "grant_type="+GRANT_TYPE+"&appid="+APP_ID+"&secret="+SECRET;
- try{
- URL realUrl = new URL(url);
- // 打开和URL之间的连接
- HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
- connection.setRequestMethod("GET");
- connection.connect();
- // 获取所有响应头字段
- Map<String, List<String>> map = connection.getHeaderFields();
- // 遍历所有的响应头字段
- for (String key : map.keySet()) {
- System.err.println(key + "--->" + map.get(key));
- }
- // 定义 BufferedReader输入流来读取URL的响应
- BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
- String result = "";
- String line;
- while ((line = in.readLine()) != null) {
- result += line;
- }
- JSONObject jsonObject = new JSONObject(result);
- return jsonObject.getString("access_token");
- } catch (Exception e) {
- System.err.printf("获取token失败!");
- e.printStackTrace(System.err);
- return "";
- }
- }
- }
步骤二:配置定时器:
在spring的xml中配置:
- <!-- 定时器配置 -->
- <task:annotation-driven scheduler="myScheduler"/>
- <task:scheduler id="myScheduler" pool-size="5"/>
注意:写定时方法的类必须在spring能够扫描的到的包下
步骤三:配置redis(如果不用redis可以跳过此步骤,直接把access_token保存到数据库或者配置文件中就可以了)
1.前提是本机装了redis,网上有很多教程,本文不做过多介绍,并不复杂
2.引入项目需要的redis依赖
- <!-- redis 依赖 -->
- <dependency>
- <groupId>redis.clients</groupId>
- <artifactId>jedis</artifactId>
- <version>2.9.0</version>
- <type>jar</type>
- </dependency>
3.配置reids连接(跟配置jdbc连接类似)
- redis.host=127.0.0.1
- redis.port=6379
- redis.timeout=3000
4.新建一个reids.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
- <context:property-placeholder location="classpath:redis.properties" />
- <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" />
- <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool" scope="singleton" >
- <constructor-arg index="0" ref="jedisPoolConfig" />
- <constructor-arg index="1">
- <list>
- <bean class="redis.clients.jedis.JedisShardInfo">
- <constructor-arg name="host" value="${redis.host}"/>
- <constructor-arg name="port" value="${redis.port}"/>
- <constructor-arg name="timeout" value="${redis.timeout}"/>
- </bean>
- </list>
- </constructor-arg>
- </bean>
- </beans>
5.将redis.xml引入到spring的xml中
- <import resource="redis.xml"/>
6.编写一个redis连接池的类,包含安全关闭连接池的方法,同样也要使这个类能够被spring所扫描到
- package com.encore.service;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Service;
- import redis.clients.jedis.ShardedJedis;
- import redis.clients.jedis.ShardedJedisPool;
- import javax.annotation.Resource;
- @Service("redisPool")
- @Slf4j
- public class RedisPool {
- @Resource(name = "shardedJedisPool")
- private ShardedJedisPool shardedJedisPool;
- public ShardedJedis instance(){
- return shardedJedisPool.getResource();
- }
- public void safeClose(ShardedJedis shardedJedis){
- try {
- if (shardedJedis != null){
- shardedJedis.close();
- }
- }catch (Exception e){
- log.error("redis 关闭异常", e);
- }
- }
- }
7.封装一个类,提供把数据写入redis和从redis中读取数据的方法,也要让这个类被spring所管理
- package com.encore.service;
- import org.springframework.stereotype.Service;
- import redis.clients.jedis.ShardedJedis;
- import javax.annotation.Resource;
- @Service("redisCacheService")
- public class RedisCacheService {
- // 注入RedisPool
- @Resource(name = "redisPool")
- private RedisPool redisPool;
- /**
- * 把要存储的值放进缓存
- * @param cacheKey 键值,可以用来获取要存储的值
- * @param toSavedValue 要存储的值
- * @param timeOutSeconds 过期时间 单位为秒
- */
- public void saveCache(String cacheKey, String toSavedValue, int timeOutSeconds){
- if (toSavedValue == null){
- return;
- }
- ShardedJedis shardedJedis = null;
- try {
- shardedJedis = redisPool.instance();
- shardedJedis.setex(cacheKey, timeOutSeconds, toSavedValue);
- }catch (Exception e){
- e.printStackTrace();
- }finally {
- redisPool.safeClose(shardedJedis);
- }
- }
- /**
- * 根据键值从缓存中获取数据
- * @param cacheKey 缓存的键值
- * @return
- */
- public String getFromCache(String cacheKey){
- ShardedJedis shardedJedis = null;
- try {
- shardedJedis = redisPool.instance();
- String value = shardedJedis.get(cacheKey);
- return value;
- }catch (Exception e){
- return null;
- }finally {
- redisPool.safeClose(shardedJedis);
- }
- }
- }
步骤四:实现定时器的方法(这个类要可以被spring扫描的到),实现每1.5小时获取一次access_token,并将其放到redis,同时保证可以从redis中读取出来
- package com.encore.service;
- import com.encore.util.WeChatTokenUtil;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Component;
- import javax.annotation.Resource;
- @Component
- public class TaskService {
- @Resource
- private RedisCacheService redisCacheService;
- private static final String TOKEN_KEY = "my_wechat_token";
- @Scheduled(fixedRate= 1000*60*90, initialDelay = 2000)//项目启动2秒中之后执行一次,然后每90min执行一次,单位都为ms
- public void getToken(){
- //1. 获取token
- String access_token = WeChatTokenUtil.getToken();
- System.out.println("从微信服务器获取的token======"+access_token);
- redisCacheService.saveCache(TOKEN_KEY, access_token ,60*120);
- String getToken = redisCacheService.getFromCache(TOKEN_KEY);
- System.out.println("从redis中获取的token === "+getToken);
- }
- }
最后,在开启项目进行测试的时候,先把redis服务器打开,经测试,可以正常获取access_token,也可以存放到redis中,同时也可以从redis中读取出来,如图所示,可以从Redis Desktop Manager中看得到存放进去的access_token:
Java微信公众号开发----定时获取access_token并保存到redis中的更多相关文章
- Java微信公众号开发梳理
Java微信公众号开发梳理 现在微信公众平台的开发已经越来越普遍,这次开发需要用到微信公众平台.因此做一个简单的记录,也算是给那些没踩过坑的童鞋一些启示吧.我将分几块来简单的描述一下,之后会做详细的说 ...
- Java微信公众号开发
微信公众平台是腾讯为了让用户申请和管理微信公众账号而推出的一个web平台.微信公众账号的种类可以分为3种,并且一旦选定不可更改.按照功能的限制从小到大依次为:订阅号.服务号.企业号.个人只能注册订阅号 ...
- 微信公众号开发及时获取当前用户Openid及注意事项
目录 (一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 (四)微信公众号开发之网页授权获取用户基本信息 (五)微信公众号开发之网页中及 ...
- 微信公众号开发系列-获取微信OpenID
在微信开发时候在做消息接口交互的时候须要使用带微信加密ID(OpenId),下面讲讲述2中类型方式获取微信OpenID.接收事件推送方式和网页授权获取用户基本信息方式获取. 1.通过接收被动消息方式获 ...
- Java微信公众号开发----关键字自动回复消息
在配置好开发者配置后,本人第一个想要实现的是自动回复消息的功能,说明以下几点: 1. url 仍然不变,还是开发配置里的url 2. 微信采用 xml 格式传输数据 3.微信服务器传给我们的参数主要有 ...
- Java微信公众号开发-外网映射工具配置
一.开发环境准备 1.一个微信公众号 2.外网映射工具(开发调试)如花生壳.ngrok工具 注:与微信对接的URL要具备以下条件a:在公网上能够访问 b:端口只支持80端口 这里使用ngrok.cc: ...
- 初识Java微信公众号开发
选定类型后不可更改 企业号与服务号,订阅号的区别 公众号微信注册流程: 个人就选择订阅号 外网映射 必须要使用映射工具将本地的地址映射到公网上去 介绍一个ngrok 首先下载ngork,例如保存在D盘 ...
- Java 微信公众号开发--- 接入微信
开发微信公众号在没有正式的公众平台账号时,我们可以使用测试平台账号--- 测试平台申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandb ...
- tp6微信公众号开发者模式获取access_token
1:config 文件下新建一个文件wechat.php,将个人id和秘钥写入配置文件 网址: https://developers.weixin.qq.com/doc/offiaccount/Bas ...
随机推荐
- 云服务器、虚拟主机和VPS的区别
虚拟主机就是利用网络空间技术,把一台服务器分成许多的"虚拟"的主机,每一台网络空间都具有独立的域名和IP地址,具有完整的Internet服务器功能.网络空间之间完全独立,在外界看来 ...
- 5G时代的智慧物流~圆通副总裁相峰
图片来自“百度百科” 本文是圆通速递CEO.国家工程实验室主任相峰先生在2019全球物流技术大会的演讲,在演讲中,相峰先生主要阐述了自己对5G的看法以及5G在物流领域的应用. 以下是演 ...
- IT兄弟连 Java语法教程 Java语言的跨平台特性
什么是平台 Java是可以跨平台的编程语言,那么首先我们需要知道什么是平台,通常我们把CPU与操作系统的整体称为平台. CPU大家都知道,是计算机的大脑,它既负责思维运算,又负责计算机中各种零部件的命 ...
- 一、接口测试——HTTPRunner二次开发之参数化一
目前项目中在使用开源框架HTTPRunner,时间使用过程中会用到生成随机信息的方法,如生成随机姓名.随机手机号.身份证号.姓名.地址等.以下对二次开发的过程进行简要描述. 一.需求 1.需要测试的接 ...
- atom 插件 python语法验证linter-flake8-------填坑
python的语法相对于一般语言的语法比较严格.对于刚刚从前端入门python的我来说,有时候代码写完了,然后报错,好多语法错误.所以这个时候一个好的语法验证插件是很好的.linter-flake8这 ...
- js 获取两个日期相差的天数--自定义方法
//获取两个日期的相差天数 datedifference=function(sDate1, sDate2) { var dateSpan, tempDate, iDays; sDate1 = Date ...
- luogu P2709 小B的询问 最简单的莫队
块内按右端点sort,块外按左端点sort 话说我刚开始这么修改... inline )*(c[a[i]]-),--c[a[i]];} inline )*(c[a[i]]+),++c[a[i]];} ...
- 1081 Rational Sum(20 分)
Given N rational numbers in the form numerator/denominator, you are supposed to calculate their sum. ...
- stm32的低功耗模式:
一.待机模式.待机模式是低功耗中最低功耗的,内部电压调节电路被关闭, HSE.HIS.PLL被关闭:进入待机模式后,SRAM和寄存器的内容将丢失. (CPU停止,外设停止,RAM的数据寄存器的内容 ...
- 《springcloud 一》搭建注册中心,服务提供者,服务消费者
注册中心环境搭建 Maven依赖信息 <parent> <groupId>org.springframework.boot</groupId> <artifa ...