添加MemcacheTokenStorager支持 #62
This commit is contained in:
@@ -12,7 +12,7 @@ import com.foxinmy.weixin4j.util.FileUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
/**
|
||||
* 用FILE保存TOKEN
|
||||
* 用File形式保存Token信息
|
||||
*
|
||||
* @className FileTokenStorager
|
||||
* @author jy
|
||||
@@ -29,14 +29,17 @@ public class FileTokenStorager implements TokenStorager {
|
||||
|
||||
@Override
|
||||
public Token lookup(String cacheKey) throws WeixinException {
|
||||
File token_file = new File(String.format("%s/%s.xml", cachePath, cacheKey));
|
||||
File token_file = new File(String.format("%s/%s.xml", cachePath,
|
||||
cacheKey));
|
||||
try {
|
||||
if (token_file.exists()) {
|
||||
Token token = XmlStream.fromXML(new FileInputStream(token_file), Token.class);
|
||||
Token token = XmlStream.fromXML(
|
||||
new FileInputStream(token_file), Token.class);
|
||||
if (token.getCreateTime() < 0) {
|
||||
return token;
|
||||
}
|
||||
if ((token.getCreateTime() + (token.getExpiresIn() * 1000l) - CUTMS) > System.currentTimeMillis()) {
|
||||
if ((token.getCreateTime() + (token.getExpiresIn() * 1000l) - CUTMS) > System
|
||||
.currentTimeMillis()) {
|
||||
return token;
|
||||
}
|
||||
}
|
||||
@@ -49,7 +52,10 @@ public class FileTokenStorager implements TokenStorager {
|
||||
@Override
|
||||
public void caching(String cacheKey, Token token) throws WeixinException {
|
||||
try {
|
||||
XmlStream.toXML(token, new FileOutputStream(new File(String.format("%s/%s.xml", cachePath, cacheKey))));
|
||||
XmlStream.toXML(
|
||||
token,
|
||||
new FileOutputStream(new File(String.format("%s/%s.xml",
|
||||
cachePath, cacheKey))));
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e);
|
||||
}
|
||||
@@ -58,10 +64,12 @@ public class FileTokenStorager implements TokenStorager {
|
||||
@Override
|
||||
public Token evict(String cacheKey) throws WeixinException {
|
||||
Token token = null;
|
||||
File token_file = new File(String.format("%s/%s.xml", cachePath, cacheKey));
|
||||
File token_file = new File(String.format("%s/%s.xml", cachePath,
|
||||
cacheKey));
|
||||
try {
|
||||
if (token_file.exists()) {
|
||||
token = XmlStream.fromXML(new FileInputStream(token_file), Token.class);
|
||||
token = XmlStream.fromXML(new FileInputStream(token_file),
|
||||
Token.class);
|
||||
token_file.delete();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@@ -75,8 +83,10 @@ public class FileTokenStorager implements TokenStorager {
|
||||
File[] files = new File(cachePath).listFiles(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return file.isFile() && file.getName().startsWith(PREFIX)
|
||||
&& "xml".equals(FileUtil.getFileExtension(file.getName()));
|
||||
return file.isFile()
|
||||
&& file.getName().startsWith(PREFIX)
|
||||
&& "xml".equals(FileUtil.getFileExtension(file
|
||||
.getName()));
|
||||
}
|
||||
});
|
||||
for (File token : files) {
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
package com.foxinmy.weixin4j.token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.danga.MemCached.MemCachedClient;
|
||||
import com.danga.MemCached.SockIOPool;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
|
||||
/**
|
||||
* 用Memcache保存Token信息(推荐使用)
|
||||
*
|
||||
* @className MemcacheTokenStorager
|
||||
* @author jy
|
||||
* @date 2016年5月11日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class MemcacheTokenStorager implements TokenStorager {
|
||||
|
||||
private final MemCachedClient mc;
|
||||
|
||||
public MemcacheTokenStorager(MemcachePoolConfig poolConfig) {
|
||||
mc = new MemCachedClient();
|
||||
poolConfig.initSocketIO();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token lookup(String cacheKey) throws WeixinException {
|
||||
return (Token) mc.get(cacheKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void caching(String cacheKey, Token token) throws WeixinException {
|
||||
if (token.getExpiresIn() > 0) {
|
||||
mc.set(cacheKey, token,
|
||||
new Date(token.getCreateTime() + token.getExpiresIn()
|
||||
* 1000 - CUTMS));
|
||||
} else {
|
||||
mc.set(cacheKey, token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token evict(String cacheKey) throws WeixinException {
|
||||
Token token = lookup(cacheKey);
|
||||
mc.delete(cacheKey);
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() throws WeixinException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static class MemcachePoolConfig {
|
||||
public final static String HOST = "localhost";
|
||||
public final static int PORT = 11211;
|
||||
public final static int WEIGHT = 1;
|
||||
|
||||
public static int minConn = 5;
|
||||
public static int initConn = 5;
|
||||
public static int maxConn = 100;
|
||||
public static long maxIdle = 300000L;
|
||||
public static long maxBusyTime = 30000L;
|
||||
public static int socketTO = 3000;
|
||||
public static int socketConnectTO = 3000;
|
||||
public static boolean failover = true;
|
||||
public static boolean failback = true;
|
||||
public static boolean nagle = false;
|
||||
public static boolean aliveCheck = false;
|
||||
public static final int consistentHash = 3;
|
||||
public static final int mainSleep = 30000;
|
||||
|
||||
private static SockIOPool pool;
|
||||
static {
|
||||
pool = SockIOPool.getInstance();
|
||||
pool.setFailback(failback);
|
||||
pool.setFailover(failover);
|
||||
pool.setMaxBusyTime(maxBusyTime);
|
||||
pool.setMaxConn(maxConn);
|
||||
pool.setMaxIdle(maxIdle);
|
||||
pool.setMinConn(minConn);
|
||||
pool.setNagle(nagle);
|
||||
pool.setSocketConnectTO(socketConnectTO);
|
||||
pool.setSocketTO(socketTO);
|
||||
pool.setAliveCheck(aliveCheck);
|
||||
pool.setHashingAlg(consistentHash);
|
||||
pool.setInitConn(initConn);
|
||||
pool.setMaintSleep(maxBusyTime);
|
||||
}
|
||||
|
||||
private List<MemcacheConfig> configs;
|
||||
private String[] servers;
|
||||
private Integer[] weights;
|
||||
|
||||
/**
|
||||
* {localhost:11211,1}
|
||||
*/
|
||||
public MemcachePoolConfig() {
|
||||
this(HOST, PORT, WEIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
* {host:11211,1}
|
||||
*
|
||||
* @param host
|
||||
* 主机
|
||||
*/
|
||||
public MemcachePoolConfig(String host) {
|
||||
this(host, PORT);
|
||||
}
|
||||
|
||||
/**
|
||||
* {host:port,1}
|
||||
*
|
||||
* @param host
|
||||
* 主机
|
||||
* @param port
|
||||
* 端口
|
||||
*/
|
||||
public MemcachePoolConfig(String host, int port) {
|
||||
this(host, port, WEIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
* {host:port,weight}
|
||||
*
|
||||
* @param host
|
||||
* 主机
|
||||
* @param port
|
||||
* 端口
|
||||
* @param weight
|
||||
* 权重
|
||||
*/
|
||||
public MemcachePoolConfig(String host, int port, int weight) {
|
||||
configs = new ArrayList<MemcacheConfig>();
|
||||
configs.add(new MemcacheConfig(host, port, weight));
|
||||
}
|
||||
|
||||
public MemcachePoolConfig addServer(String host) {
|
||||
return addServer(host, PORT, WEIGHT);
|
||||
}
|
||||
|
||||
public MemcachePoolConfig addServer(String host, int port) {
|
||||
return addServer(host, port, WEIGHT);
|
||||
}
|
||||
|
||||
public MemcachePoolConfig addServer(String host, int port, int weight) {
|
||||
configs.add(new MemcacheConfig(host, port, weight));
|
||||
return this;
|
||||
}
|
||||
|
||||
private void initConfig() {
|
||||
if (servers == null || weights == null) {
|
||||
servers = new String[configs.size()];
|
||||
weights = new Integer[configs.size()];
|
||||
for (int i = 0; i < configs.size(); i++) {
|
||||
servers[i] = configs.get(i).getServer();
|
||||
weights[i] = configs.get(i).getWeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initSocketIO() {
|
||||
pool.setServers(getServers());
|
||||
pool.setWeights(getWeights());
|
||||
if (pool.isInitialized()) {
|
||||
pool.shutDown();
|
||||
}
|
||||
pool.initialize();
|
||||
}
|
||||
|
||||
public String[] getServers() {
|
||||
initConfig();
|
||||
return servers;
|
||||
}
|
||||
|
||||
public Integer[] getWeights() {
|
||||
initConfig();
|
||||
return weights;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MemcachePoolConfig [" + configs + "]";
|
||||
}
|
||||
|
||||
private static class MemcacheConfig {
|
||||
private String host;
|
||||
private int port;
|
||||
private int weight;
|
||||
|
||||
public MemcacheConfig(String host, int port, int weight) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public String getServer() {
|
||||
return String.format("%s:%d", host, port);
|
||||
}
|
||||
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("{%s:%d,%d}", host, port, weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
|
||||
/**
|
||||
* 用内存保存TOKEN(不推荐使用)
|
||||
* 用内存保存Token信息(不推荐使用)
|
||||
*
|
||||
* @className MemoryTokenStorager
|
||||
* @author jy
|
||||
|
||||
@@ -8,4 +8,6 @@
|
||||
|
||||
* FileTokenStorager 是系统默认的token存储策略实现
|
||||
|
||||
* RedisTokenStorager 如果服务器支持redis,推荐使用(需要自己添加jedis包)
|
||||
* RedisTokenStorager 使用redis保存token(需要自行添加客户端包,[jedis](https://github.com/xetorthio/jedis))
|
||||
|
||||
* MemcacheTokenStorager 使用memcache保存token(需要自行添加客户端包,[Memcached-Java-Client](https://github.com/gwhalin/Memcached-Java-Client))
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
|
||||
/**
|
||||
* 用REDIS保存TOKEN(推荐使用)
|
||||
* 用Redis保存Token信息(推荐使用)
|
||||
*
|
||||
* @className RedisTokenStorager
|
||||
* @author jy
|
||||
@@ -24,15 +24,16 @@ public class RedisTokenStorager implements TokenStorager {
|
||||
|
||||
private JedisPool jedisPool;
|
||||
|
||||
public final static String HOST = "localhost";
|
||||
public final static int PORT = 6379;
|
||||
public final static int MAX_TOTAL = 50;
|
||||
public final static int MAX_IDLE = 5;
|
||||
public final static int MAX_WAIT_MILLIS = 2000;
|
||||
public final static int MAX_WAIT_MILLIS = 3000;
|
||||
public final static boolean TEST_ON_BORROW = false;
|
||||
public final static boolean TEST_ON_RETURN = true;
|
||||
|
||||
public RedisTokenStorager() {
|
||||
this("localhost", PORT);
|
||||
this(HOST, PORT);
|
||||
}
|
||||
|
||||
public RedisTokenStorager(String host, int port) {
|
||||
@@ -45,7 +46,8 @@ public class RedisTokenStorager implements TokenStorager {
|
||||
this.jedisPool = new JedisPool(jedisPoolConfig, host, port);
|
||||
}
|
||||
|
||||
public RedisTokenStorager(String host, int port, JedisPoolConfig jedisPoolConfig) {
|
||||
public RedisTokenStorager(String host, int port,
|
||||
JedisPoolConfig jedisPoolConfig) {
|
||||
this(new JedisPool(jedisPoolConfig, host, port));
|
||||
}
|
||||
|
||||
@@ -77,7 +79,8 @@ public class RedisTokenStorager implements TokenStorager {
|
||||
jedis = jedisPool.getResource();
|
||||
jedis.hmset(cacheKey, token2map(token));
|
||||
if (token.getExpiresIn() > 0) {
|
||||
jedis.expire(cacheKey, token.getExpiresIn() - (int) (CUTMS / 1000l));
|
||||
jedis.expire(cacheKey, token.getExpiresIn()
|
||||
- (int) (CUTMS / 1000l));
|
||||
}
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.foxinmy.weixin4j.model.Token;
|
||||
* @see MemoryTokenStorager
|
||||
* @see FileTokenStorager
|
||||
* @see RedisTokenStorager
|
||||
* @see MemcacheTokenStorager
|
||||
*/
|
||||
public interface TokenStorager extends CacheStorager<Token> {
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user