修缮token实现机制

This commit is contained in:
jinyu
2015-06-12 14:38:32 +08:00
parent 76ae9d58e3
commit dea8ab6252
15 changed files with 242 additions and 134 deletions
@@ -1,60 +0,0 @@
package com.foxinmy.weixin4j.token;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.xml.XmlStream;
/**
* 用FILE保存TOKEN
*
* @className FileTokenHolder
* @author jy
* @date 2015年1月9日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.token.TokenCreator
*/
public class FileTokenHolder implements TokenHolder {
private final String tokenPath;
private final TokenCreator tokenCreator;
public FileTokenHolder(TokenCreator tokenCreator) {
this(ConfigUtil.getValue("token_path"), tokenCreator);
}
public FileTokenHolder(String tokenPath, TokenCreator tokenCreator) {
this.tokenPath = tokenPath;
this.tokenCreator = tokenCreator;
}
@Override
public Token getToken() throws WeixinException {
File token_file = new File(String.format("%s/%s.xml", tokenPath,
tokenCreator.getCacheKey()));
Token token = null;
Calendar ca = Calendar.getInstance();
long now_time = ca.getTimeInMillis();
try {
if (token_file.exists()) {
token = XmlStream.fromXML(new FileInputStream(token_file),
Token.class);
long expire_time = token.getTime()
+ (token.getExpiresIn() * 1000) - 2;
if (expire_time > now_time) {
return token;
}
}
token = tokenCreator.createToken();
XmlStream.toXML(token, new FileOutputStream(token_file));
} catch (IOException e) {
throw new WeixinException(e.getMessage());
}
return token;
}
}
@@ -0,0 +1,65 @@
package com.foxinmy.weixin4j.token;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.xml.XmlStream;
/**
* 用FILE保存TOKEN
*
* @className FileTokenStorager
* @author jy
* @date 2015年1月9日
* @since JDK 1.7
*/
public class FileTokenStorager implements TokenStorager {
private final String tokenPath;
public FileTokenStorager() {
this(ConfigUtil.getValue("token_path"));
}
public FileTokenStorager(String tokenPath) {
this.tokenPath = tokenPath;
}
@Override
public Token lookupToken(String cacheKey) throws WeixinException {
File token_file = new File(String.format("%s/%s.xml", tokenPath,
cacheKey));
try {
if (token_file.exists()) {
Token token = XmlStream.fromXML(
new FileInputStream(token_file), Token.class);
long expire_time = token.getTime()
+ (token.getExpiresIn() * 1000) - 2;
if (expire_time > System.currentTimeMillis()) {
return token;
}
}
return null;
} catch (IOException e) {
throw new WeixinException(e.getMessage());
}
}
@Override
public void cachingToken(Token token, String cacheKey)
throws WeixinException {
try {
XmlStream.toXML(
token,
new FileOutputStream(new File(String.format("%s/%s.xml",
tokenPath, cacheKey))));
} catch (IOException e) {
throw new WeixinException(e.getMessage());
}
}
}
@@ -1,6 +1,11 @@
### TOKEN的实现
TokenHolder.java token持有者接口<br>
FileTokenHolder.java 基于文件保存的TokenHolder实现<br>
RedisTokenHolder.java 基于redis保存的TokenHolder实现(推荐)<br>
TokenCreator.java token创建者接口
* TokenCreator 负责创建新的token
* TokenStorager 负责查找已缓存的token或者缓存新的token
* TokenHolder 负责获取token(屏蔽了获取方式)
* FileTokenStorager 是系统默认的token存储策略实现
* RedisTokenStorager 如果服务器支持redis,推荐使用(需要自己添加jar包和[java类](https://github.com/foxinmy/weixin4j/wiki/%E7%94%A8redis%E4%BF%9D%E5%AD%98token))
@@ -1,19 +1,35 @@
package com.foxinmy.weixin4j.token;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token;
/**
* token持有者
*
* @className TokenHolder
* @author jy.hu
* @date 2014年9月27
* @since JDK 1.7
* @see com.foxinmy.weixin4j.model.Token
* @see com.foxinmy.weixin4j.token.FileTokenHolder
* @see com.foxinmy.weixin4j.token.RedisTokenHolder
*/
public interface TokenHolder {
public Token getToken() throws WeixinException;
}
package com.foxinmy.weixin4j.token;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token;
/**
* token的缓存获取
*
* @className TokenHolder
* @author jy
* @date 2015年6月12
* @since JDK 1.7
* @see TokenCreator
* @see TokenStorager
*/
public final class TokenHolder {
private final TokenCreator tokenCreator;
private final TokenStorager tokenStorager;
public TokenHolder(TokenCreator tokenCreator, TokenStorager tokenStorager) {
this.tokenCreator = tokenCreator;
this.tokenStorager = tokenStorager;
}
public Token getToken() throws WeixinException {
String cacheKey = tokenCreator.getCacheKey();
Token token = tokenStorager.lookupToken(cacheKey);
if (token == null) {
token = tokenCreator.createToken();
tokenStorager.cachingToken(token, cacheKey);
}
return token;
}
}
@@ -0,0 +1,39 @@
package com.foxinmy.weixin4j.token;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token;
/**
* token的存储
*
* @className TokenStorager
* @author jy.hu
* @date 2014年9月27日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.model.Token
* @see com.foxinmy.weixin4j.token.FileTokenStorager
* @see com.foxinmy.weixin4j.token.RedisTokenStorager
*/
public interface TokenStorager {
/**
* 查找缓存的token
*
* @param cacheKey
* 缓存的名称
* @return 查找结果
* @throws WeixinException
*/
public Token lookupToken(String cacheKey) throws WeixinException;
/**
* 缓存新的token
*
* @param token
* 新产生的token
* @param cacheKey
* 缓存的名称
* @throws WeixinException
*/
public void cachingToken(Token token, String cacheKey)
throws WeixinException;
}