热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

javatoken缓存_SpringBoot中微信全局token的缓存实现

为什么要缓存token?这里的token指的是微信JSAPI中基础支持的ACCESS_TOKEN,并非网页授权ACCESS_TOKEN。网页授权Token每天的调用次

为什么要缓存token?

这里的token指的是微信JSAPI中基础支持的ACCESS_TOKEN,并非网页授权ACCESS_TOKEN。网页授权Token每天的调用次数没有限制,不需要缓存。

接口每日限额

获取access_token

2000

自定义菜单创建

1000

自定义菜单查询

10000

获取用户基本信息

5000000

获取网页授权access_token

刷新网页授权access_token

网页授权获取用户信息

从上面的表格我们可以看到,微信基础支持的token每天调用频次为2000次。而token的有效时间为7200s,当实现了token的全局缓存后,理论每天只需要调用12次。相反,2000次即使仅供微信分享回调,在有一定用户基础的项目中完全满足不了。

缓存方案

项目启动时开启一个定时器,每7180s执行一次Http请求,从微信获取最新的access_token并将redis中旧的access_token替换掉。

代码中有需要使用access_token时,直接从缓存中读取。

Spring Boot使用定时器

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import java.sql.SQLException;

import javax.annotation.Resource;

import org.apache.log4j.Logger;

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Component;

import com.bjb.dao.impl.RedisTokenHelper;

import net.sf.json.JSONObject;

/**

* 全局定时器

* @author qiqj

*

*/

@Component

public class Scheduler {

private final Logger logger = Logger.getRootLogger();

@Resource

private RedisTokenHelper redisTokenHelper;

/**

* 定时获取access_token

* @throws SQLException

*/

@Scheduled(fixedDelay=7180000)

public void getAccessToken() throws SQLException{

logger.info("==============开始获取access_token===============");

String access_token = null;

String grant_type = "client_credential";

String AppId= WxPropertiseUtil.getProperty("appid");

String secret= WxPropertiseUtil.getProperty("secret");

String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type="+grant_type+"&appid="+AppId+"&secret="+secret;

try {

URL urlGet = new URL(url);

HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();

http.setRequestMethod("GET"); // 必须是get方式请求

http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

http.setDoOutput(true);

http.setDoInput(true);

http.connect();

InputStream is = http.getInputStream();

int size = is.available();

byte[] jsonBytes = new byte[size];

is.read(jsonBytes);

String message = new String(jsonBytes, "UTF-8");

JSONObject demoJson = JSONObject.fromObject(message);

//System.out.println("JSON字符串:"+demoJson);

access_token = demoJson.getString("access_token");

is.close();

logger.info("==============结束获取access_token===============");

} catch (Exception e) {

e.printStackTrace();

}

logger.info("==============开始写入access_token===============");

redisTokenHelper.saveObject("global_token", access_token);

logger.info("==============写入access_token成功===============");

}

}

读取配置文件工具类

import java.io.IOException;

import java.io.InputStream;

import java.util.Properties;

import org.apache.log4j.Logger;

/**

* 读取微信配置文件 wxconfig.properties工具类

*@author qiqj

*

*/

public class WxPropertiseUtil {

private static Properties properties = new Properties();

protected static final Logger logger = Logger.getRootLogger();

static{

InputStream in = WxPropertiseUtil.class.getClassLoader().getResourceAsStream("wxconfig.properties");

try {

properties.load(in);

} catch (IOException e) {

e.printStackTrace();

logger.error(e.getMessage());

}

}

public static String getProperty(String key){

return properties.getProperty(key);

}

public static void UpdateProperty(String key,String value){

properties.setProperty(key, value);

}

}

微信配置文件

appid=xxxx

secret=xxxxxx

Redis操作工具类

import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.data.redis.core.ValueOperations;

import org.springframework.stereotype.Repository;

/**

* 封装Redis存取Token对的工具类

*@author qiqj

*

*/

@Repository

public class RedisTokenHelper {

@Autowired

StringRedisTemplate stringRedisTemplate;

@Autowired

RedisTemplate redisTemplate;

@Resource(name="stringRedisTemplate")

ValueOperations ops;

@Resource(name="redisTemplate")

ValueOperations objOps;

/**

* 键值对存储 字符串 :有效时间3分钟

*@param tokenType Token的key

*@param Token Token的值

*/

public void save(String tokenType,String Token){

ops.set(tokenType, Token, 180, TimeUnit.SECONDS);

}

/**

* 根据key从redis获取value

*@param tokenType

*@return String

*/

public String getToken(String tokenType){

return ops.get(tokenType);

}

/**

* redis 存储一个对象

*@param key

*@param obj

*@param timeout 过期时间 单位:s

*/

public void saveObject(String key,Object obj,long timeout){

objOps.set(key, obj,timeout,TimeUnit.SECONDS);

}

/**

* redis 存储一个对象 ,不过期

*@param key

*@param obj

*/

public void saveObject(String key,Object obj){

objOps.set(key, obj);

}

/**

* 从redis取出一个对象

*@param key

*@param obj

*/

public Object getObject(String key){

return objOps.get(key);

}

/**

* 根据Key删除Object

*@param key

*/

public void removeObject(String key){

redisTemplate.delete(key);

}

}

简单测试

import org.apache.log4j.Logger;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.boot.test.SpringApplicationConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import org.springframework.test.context.web.WebAppConfiguration;

import org.springframework.transaction.annotation.Transactional;

import com.bjb.Application;

import com.bjb.dao.impl.RedisTokenHelper;

/**

* Junit单元测试类

*@author qiqj

*

*/

@RunWith(SpringJUnit4ClassRunner.class)

@SpringApplicationConfiguration(classes=Application.class)

@WebAppConfiguration

@Transactional

public class JUnitTest {

private final Logger logger = Logger.getRootLogger();

@Resource

private RedisTokenHelper redisTokenHelper;

@Test

public void test(){

String access_token = (String) redisTokenHelper.getObject("global_token");

System.out.println("access_token:"+access_token);

}

}



推荐阅读
author-avatar
周扒pi
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有