mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2026-03-10 00:13:40 +08:00
规范统一config部分代码
This commit is contained in:
@@ -1,104 +0,0 @@
|
||||
package me.chanjar.weixin.mp.api;
|
||||
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
|
||||
import me.chanjar.weixin.mp.bean.WxMpHostConfig;
|
||||
import me.chanjar.weixin.mp.enums.TicketType;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
/**
|
||||
* 微信客户端配置存储.
|
||||
*
|
||||
* @author chanjarster
|
||||
*/
|
||||
public interface WxMpConfigStorage {
|
||||
String getAccessToken();
|
||||
|
||||
Lock getAccessTokenLock();
|
||||
|
||||
boolean isAccessTokenExpired();
|
||||
|
||||
/**
|
||||
* 强制将access token过期掉.
|
||||
*/
|
||||
void expireAccessToken();
|
||||
|
||||
/**
|
||||
* 应该是线程安全的.
|
||||
*
|
||||
* @param accessToken 要更新的WxAccessToken对象
|
||||
*/
|
||||
void updateAccessToken(WxAccessToken accessToken);
|
||||
|
||||
/**
|
||||
* 应该是线程安全的.
|
||||
*
|
||||
* @param accessToken 新的accessToken值
|
||||
* @param expiresInSeconds 过期时间,以秒为单位
|
||||
*/
|
||||
void updateAccessToken(String accessToken, int expiresInSeconds);
|
||||
|
||||
String getTicket(TicketType type);
|
||||
|
||||
Lock getTicketLock(TicketType type);
|
||||
|
||||
boolean isTicketExpired(TicketType type);
|
||||
|
||||
/**
|
||||
* 强制将ticket过期掉.
|
||||
*/
|
||||
void expireTicket(TicketType type);
|
||||
|
||||
/**
|
||||
* 更新ticket.
|
||||
* 应该是线程安全的
|
||||
*
|
||||
* @param type ticket类型
|
||||
* @param ticket 新的ticket值
|
||||
* @param expiresInSeconds 过期时间,以秒为单位
|
||||
*/
|
||||
void updateTicket(TicketType type, String ticket, int expiresInSeconds);
|
||||
|
||||
String getAppId();
|
||||
|
||||
String getSecret();
|
||||
|
||||
String getToken();
|
||||
|
||||
String getAesKey();
|
||||
|
||||
String getTemplateId();
|
||||
|
||||
long getExpiresTime();
|
||||
|
||||
String getOauth2redirectUri();
|
||||
|
||||
String getHttpProxyHost();
|
||||
|
||||
int getHttpProxyPort();
|
||||
|
||||
String getHttpProxyUsername();
|
||||
|
||||
String getHttpProxyPassword();
|
||||
|
||||
File getTmpDirFile();
|
||||
|
||||
/**
|
||||
* http client builder.
|
||||
*
|
||||
* @return ApacheHttpClientBuilder
|
||||
*/
|
||||
ApacheHttpClientBuilder getApacheHttpClientBuilder();
|
||||
|
||||
/**
|
||||
* 是否自动刷新token.
|
||||
*/
|
||||
boolean autoRefreshToken();
|
||||
|
||||
/**
|
||||
* 得到微信接口地址域名部分的自定义设置信息.
|
||||
*/
|
||||
WxMpHostConfig getHostConfig();
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
package me.chanjar.weixin.mp.api;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import lombok.Data;
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
|
||||
import me.chanjar.weixin.mp.bean.WxMpHostConfig;
|
||||
import me.chanjar.weixin.mp.enums.TicketType;
|
||||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
|
||||
|
||||
/**
|
||||
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化.
|
||||
*
|
||||
* @author chanjarster
|
||||
*/
|
||||
@Data
|
||||
public class WxMpInMemoryConfigStorage implements WxMpConfigStorage, Serializable {
|
||||
private static final long serialVersionUID = -6646519023303395185L;
|
||||
|
||||
protected volatile String appId;
|
||||
protected volatile String secret;
|
||||
protected volatile String token;
|
||||
protected volatile String templateId;
|
||||
protected volatile String accessToken;
|
||||
protected volatile String aesKey;
|
||||
protected volatile long expiresTime;
|
||||
|
||||
protected volatile String oauth2redirectUri;
|
||||
|
||||
protected volatile String httpProxyHost;
|
||||
protected volatile int httpProxyPort;
|
||||
protected volatile String httpProxyUsername;
|
||||
protected volatile String httpProxyPassword;
|
||||
|
||||
protected volatile String jsapiTicket;
|
||||
protected volatile long jsapiTicketExpiresTime;
|
||||
|
||||
protected volatile String sdkTicket;
|
||||
protected volatile long sdkTicketExpiresTime;
|
||||
|
||||
protected volatile String cardApiTicket;
|
||||
protected volatile long cardApiTicketExpiresTime;
|
||||
|
||||
protected Lock accessTokenLock = new ReentrantLock();
|
||||
protected Lock jsapiTicketLock = new ReentrantLock();
|
||||
protected Lock sdkTicketLock = new ReentrantLock();
|
||||
protected Lock cardApiTicketLock = new ReentrantLock();
|
||||
|
||||
protected volatile File tmpDirFile;
|
||||
|
||||
protected volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
|
||||
|
||||
@Override
|
||||
public boolean isAccessTokenExpired() {
|
||||
return System.currentTimeMillis() > this.expiresTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void updateAccessToken(WxAccessToken accessToken) {
|
||||
updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
|
||||
this.accessToken = accessToken;
|
||||
this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireAccessToken() {
|
||||
this.expiresTime = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTicket(TicketType type) {
|
||||
switch (type) {
|
||||
case SDK:
|
||||
return this.sdkTicket;
|
||||
case JSAPI:
|
||||
return this.jsapiTicket;
|
||||
case WX_CARD:
|
||||
return this.cardApiTicket;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setTicket(TicketType type, String ticket) {
|
||||
switch (type) {
|
||||
case JSAPI:
|
||||
this.jsapiTicket = ticket;
|
||||
break;
|
||||
case WX_CARD:
|
||||
this.cardApiTicket = ticket;
|
||||
break;
|
||||
case SDK:
|
||||
this.sdkTicket = ticket;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getTicketLock(TicketType type) {
|
||||
switch (type) {
|
||||
case SDK:
|
||||
return this.sdkTicketLock;
|
||||
case JSAPI:
|
||||
return this.jsapiTicketLock;
|
||||
case WX_CARD:
|
||||
return this.cardApiTicketLock;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTicketExpired(TicketType type) {
|
||||
switch (type) {
|
||||
case SDK:
|
||||
return System.currentTimeMillis() > this.sdkTicketExpiresTime;
|
||||
case JSAPI:
|
||||
return System.currentTimeMillis() > this.jsapiTicketExpiresTime;
|
||||
case WX_CARD:
|
||||
return System.currentTimeMillis() > this.cardApiTicketExpiresTime;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void updateTicket(TicketType type, String ticket, int expiresInSeconds) {
|
||||
switch (type) {
|
||||
case JSAPI:
|
||||
this.jsapiTicket = ticket;
|
||||
// 预留200秒的时间
|
||||
this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
|
||||
break;
|
||||
case WX_CARD:
|
||||
this.cardApiTicket = ticket;
|
||||
// 预留200秒的时间
|
||||
this.cardApiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
|
||||
break;
|
||||
case SDK:
|
||||
this.sdkTicket = ticket;
|
||||
// 预留200秒的时间
|
||||
this.sdkTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireTicket(TicketType type) {
|
||||
switch (type) {
|
||||
case JSAPI:
|
||||
this.jsapiTicketExpiresTime = 0;
|
||||
break;
|
||||
case WX_CARD:
|
||||
this.cardApiTicketExpiresTime = 0;
|
||||
break;
|
||||
case SDK:
|
||||
this.sdkTicketExpiresTime = 0;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return WxMpGsonBuilder.create().toJson(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean autoRefreshToken() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxMpHostConfig getHostConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package me.chanjar.weixin.mp.api;
|
||||
|
||||
import me.chanjar.weixin.mp.enums.TicketType;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
|
||||
/**
|
||||
* 基于Redis的微信配置provider.
|
||||
*
|
||||
* <pre>
|
||||
* 使用说明:本实现仅供参考,并不完整,
|
||||
* 比如为减少项目依赖,未加入redis分布式锁的实现,如有需要请自行实现。
|
||||
* </pre>
|
||||
*
|
||||
* @author nickwong
|
||||
*/
|
||||
@SuppressWarnings("hiding")
|
||||
public class WxMpInRedisConfigStorage extends WxMpInMemoryConfigStorage {
|
||||
private static final String ACCESS_TOKEN_KEY = "wx:access_token:";
|
||||
|
||||
/**
|
||||
* 使用连接池保证线程安全.
|
||||
*/
|
||||
protected final JedisPool jedisPool;
|
||||
|
||||
private String accessTokenKey;
|
||||
|
||||
public WxMpInRedisConfigStorage(JedisPool jedisPool) {
|
||||
this.jedisPool = jedisPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* 每个公众号生成独有的存储key.
|
||||
*/
|
||||
@Override
|
||||
public void setAppId(String appId) {
|
||||
super.setAppId(appId);
|
||||
this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId);
|
||||
}
|
||||
|
||||
private String getTicketRedisKey(TicketType type) {
|
||||
return String.format("wx:ticket:key:%s:%s", this.appId, type.getCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessToken() {
|
||||
try (Jedis jedis = this.jedisPool.getResource()) {
|
||||
return jedis.get(this.accessTokenKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccessTokenExpired() {
|
||||
try (Jedis jedis = this.jedisPool.getResource()) {
|
||||
return jedis.ttl(accessTokenKey) < 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
|
||||
try (Jedis jedis = this.jedisPool.getResource()) {
|
||||
jedis.setex(this.accessTokenKey, expiresInSeconds - 200, accessToken);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireAccessToken() {
|
||||
try (Jedis jedis = this.jedisPool.getResource()) {
|
||||
jedis.expire(this.accessTokenKey, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTicket(TicketType type) {
|
||||
try (Jedis jedis = this.jedisPool.getResource()) {
|
||||
return jedis.get(this.getTicketRedisKey(type));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTicketExpired(TicketType type) {
|
||||
try (Jedis jedis = this.jedisPool.getResource()) {
|
||||
return jedis.ttl(this.getTicketRedisKey(type)) < 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void updateTicket(TicketType type, String jsapiTicket, int expiresInSeconds) {
|
||||
try (Jedis jedis = this.jedisPool.getResource()) {
|
||||
jedis.setex(this.getTicketRedisKey(type), expiresInSeconds - 200, jsapiTicket);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireTicket(TicketType type) {
|
||||
try (Jedis jedis = this.jedisPool.getResource()) {
|
||||
jedis.expire(this.getTicketRedisKey(type), 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
|
||||
import me.chanjar.weixin.mp.enums.TicketType;
|
||||
import me.chanjar.weixin.mp.enums.WxMpApiUrl;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
|
||||
import me.chanjar.weixin.mp.enums.TicketType;
|
||||
import me.chanjar.weixin.mp.enums.WxMpApiUrl;
|
||||
import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder;
|
||||
|
||||
@@ -7,7 +7,7 @@ import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.util.http.HttpType;
|
||||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
|
||||
import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder;
|
||||
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
|
||||
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
|
||||
@@ -7,7 +7,7 @@ import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import me.chanjar.weixin.common.error.WxError;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.util.http.HttpType;
|
||||
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
|
||||
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
|
||||
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import me.chanjar.weixin.common.error.WxError;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.util.http.HttpType;
|
||||
import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo;
|
||||
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
|
||||
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
|
||||
import okhttp3.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -3,7 +3,7 @@ package me.chanjar.weixin.mp.api.impl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.util.http.URIUtil;
|
||||
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
|
||||
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.api.WxMpSubscribeMsgService;
|
||||
import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage;
|
||||
|
||||
Reference in New Issue
Block a user