本人原本是想做微信公众号菜单的创建修改删除等操作的,但是发现需要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中的更多相关文章

  1. Java微信公众号开发梳理

    Java微信公众号开发梳理 现在微信公众平台的开发已经越来越普遍,这次开发需要用到微信公众平台.因此做一个简单的记录,也算是给那些没踩过坑的童鞋一些启示吧.我将分几块来简单的描述一下,之后会做详细的说 ...

  2. Java微信公众号开发

    微信公众平台是腾讯为了让用户申请和管理微信公众账号而推出的一个web平台.微信公众账号的种类可以分为3种,并且一旦选定不可更改.按照功能的限制从小到大依次为:订阅号.服务号.企业号.个人只能注册订阅号 ...

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

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

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

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

  5. Java微信公众号开发----关键字自动回复消息

    在配置好开发者配置后,本人第一个想要实现的是自动回复消息的功能,说明以下几点: 1. url 仍然不变,还是开发配置里的url 2. 微信采用 xml 格式传输数据 3.微信服务器传给我们的参数主要有 ...

  6. Java微信公众号开发-外网映射工具配置

    一.开发环境准备 1.一个微信公众号 2.外网映射工具(开发调试)如花生壳.ngrok工具 注:与微信对接的URL要具备以下条件a:在公网上能够访问 b:端口只支持80端口 这里使用ngrok.cc: ...

  7. 初识Java微信公众号开发

    选定类型后不可更改 企业号与服务号,订阅号的区别 公众号微信注册流程: 个人就选择订阅号 外网映射 必须要使用映射工具将本地的地址映射到公网上去 介绍一个ngrok 首先下载ngork,例如保存在D盘 ...

  8. Java 微信公众号开发--- 接入微信

    开发微信公众号在没有正式的公众平台账号时,我们可以使用测试平台账号--- 测试平台申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandb ...

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

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

随机推荐

  1. [Xcode 实际操作]七、文件与数据-(5 )复制、移动、删除文件和删除文件夹

    目录:[Swift]Xcode实际操作 本文将演示如何复制.移动和删除文件. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit class ...

  2. echarts3.0 实例容器不实时更新页面的问题

    var instanceId = document.getElementById(option.echartId).getAttribute('_echarts3_instance_'); if (i ...

  3. 详解window.history

    http://blog.csdn.net/woxueliuyun/article/details/51075272

  4. 什么是语义化的HTML?有何意义?为什么要做到语义化?

    一.什么是语义化的HTML? 语义化的HTML就是正确的标签做正确的事情,能够便于开发者阅读和写出更优雅的代码的同时让网络爬虫很好地解析. 二.为什么要做到语义化? 1.有利于SEO,有利于搜索引擎爬 ...

  5. P3290 寻找第K大数

    描述 寻找第K大数 N个小朋友在一起做游戏.每个小朋友在自己的硬纸板上写一个数,然后同时举起来.接着,小y老师提一个问题,看哪个小朋友先抢答出来.问题是:在这N个数中,第K大的是哪个数?请你编程完成. ...

  6. 【翻译转载】【官方教程】Asp.Net MVC4入门指南(6):验证编辑方法和编辑视图

    本节中,您将开始修改为电影控制器所新加的操作方法和视图.然后,您将添加一个自定义的搜索页. 在浏览器地址栏里追加/Movies, 浏览到Movies页面.并进入编辑(Edit)页面. Edit(编辑) ...

  7. 记录下这周的mysql调优工作

    这周一至周四基本都在做mysql的测试和调优工作,包括erlang端对mysql的写入测试,到今天为止暂且告一段落,下周先做下其他的开发.    测试环境    使用的测试环境是aliyun的杭州节点 ...

  8. Redis sorted set(有序集合)

    Redis 有序集合是string类型元素的集合,元素不允许重复. 有序集合中的每个元素都会关联一个数值型的分数.redis正是通过分数来为集合中的成员进行从小到大的排序. 有序集合的成员是唯一的(不 ...

  9. jar包生成exe可执行程序

    1.生成工具EXE4J下载链接:https://www.ej-technologies.com/download/exe4j/files 2.安装.使用:https://blog.csdn.net/h ...

  10. 洛谷P2430 严酷的训练

    第一眼看这道题...啊哈,啥??? 仔细看一看,发现:诶, 这不是01背包吗? 两人水平值的比值*老王做题用时 可以算出WKY做每道题的用时. 那么每道题的p就可以转换成费用c[i], 价值q就是w[ ...