@@ -1,6 +1,6 @@ | |||
package com.binarywang.spring.starter.wxjava.mp; | |||
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.impl.WxMpServiceImpl; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
@@ -1,8 +1,8 @@ | |||
package com.binarywang.spring.starter.wxjava.mp; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; | |||
import me.chanjar.weixin.mp.api.WxMpInRedisConfigStorage; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; | |||
import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | |||
import org.springframework.context.annotation.Bean; | |||
@@ -34,23 +34,23 @@ public class WxMpStorageAutoConfiguration { | |||
return getWxMpInMemoryConfigStorage(); | |||
} | |||
private WxMpInMemoryConfigStorage getWxMpInMemoryConfigStorage() { | |||
WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage(); | |||
private WxMpDefaultConfigImpl getWxMpInMemoryConfigStorage() { | |||
WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl(); | |||
setWxMpInfo(config); | |||
return config; | |||
} | |||
private WxMpInRedisConfigStorage getWxMpInRedisConfigStorage() { | |||
private WxMpRedisConfigImpl getWxMpInRedisConfigStorage() { | |||
JedisPool poolToUse = jedisPool; | |||
if (poolToUse == null) { | |||
poolToUse = getJedisPool(); | |||
} | |||
WxMpInRedisConfigStorage config = new WxMpInRedisConfigStorage(poolToUse); | |||
WxMpRedisConfigImpl config = new WxMpRedisConfigImpl(poolToUse); | |||
setWxMpInfo(config); | |||
return config; | |||
} | |||
private void setWxMpInfo(WxMpInMemoryConfigStorage config) { | |||
private void setWxMpInfo(WxMpDefaultConfigImpl config) { | |||
config.setAppId(properties.getAppId()); | |||
config.setSecret(properties.getSecret()); | |||
config.setToken(properties.getToken()); | |||
@@ -14,7 +14,6 @@ public interface WxCpTpConfigStorage { | |||
/** | |||
* 设置企业微信服务器 baseUrl. | |||
* | |||
* 默认值是 https://qyapi.weixin.qq.com , 如果使用默认值,则不需要调用 setBaseApiUrl | |||
* | |||
* @param baseUrl 企业微信服务器 Url | |||
@@ -23,7 +22,6 @@ public interface WxCpTpConfigStorage { | |||
/** | |||
* 读取企业微信 API Url. | |||
* | |||
* 支持私有化企业微信服务器. | |||
*/ | |||
String getApiUrl(String path); | |||
@@ -33,7 +31,7 @@ public interface WxCpTpConfigStorage { | |||
boolean isSuiteAccessTokenExpired(); | |||
/** | |||
* 强制将suite access token过期掉 | |||
* 强制将suite access token过期掉. | |||
*/ | |||
void expireSuiteAccessToken(); | |||
@@ -46,15 +44,15 @@ public interface WxCpTpConfigStorage { | |||
boolean isSuiteTicketExpired(); | |||
/** | |||
* 强制将suite ticket过期掉 | |||
* 强制将suite ticket过期掉. | |||
*/ | |||
void expireSuiteTicket(); | |||
/** | |||
* 应该是线程安全的 | |||
* 应该是线程安全的. | |||
*/ | |||
void updateSuiteTicket(String suiteTicket, int expiresInSeconds); | |||
String getCorpId(); | |||
String getCorpSecret(); | |||
@@ -80,7 +78,7 @@ public interface WxCpTpConfigStorage { | |||
File getTmpDirFile(); | |||
/** | |||
* http client builder | |||
* http client builder. | |||
* | |||
* @return ApacheHttpClientBuilder | |||
*/ | |||
@@ -1,45 +1,49 @@ | |||
package me.chanjar.weixin.cp.config; | |||
package me.chanjar.weixin.cp.config.impl; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | |||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | |||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||
import java.io.File; | |||
import java.io.Serializable; | |||
/** | |||
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 | |||
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化. | |||
* | |||
* @author Daniel Qian | |||
*/ | |||
public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
protected volatile String corpId; | |||
protected volatile String corpSecret; | |||
public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable { | |||
private static final long serialVersionUID = 1154541446729462780L; | |||
protected volatile String token; | |||
private volatile String corpId; | |||
private volatile String corpSecret; | |||
private volatile String token; | |||
protected volatile String accessToken; | |||
protected volatile String aesKey; | |||
private volatile String aesKey; | |||
protected volatile Integer agentId; | |||
protected volatile long expiresTime; | |||
private volatile long expiresTime; | |||
protected volatile String oauth2redirectUri; | |||
private volatile String oauth2redirectUri; | |||
protected volatile String httpProxyHost; | |||
protected volatile int httpProxyPort; | |||
protected volatile String httpProxyUsername; | |||
protected volatile String httpProxyPassword; | |||
private volatile String httpProxyHost; | |||
private volatile int httpProxyPort; | |||
private volatile String httpProxyUsername; | |||
private volatile String httpProxyPassword; | |||
protected volatile String jsapiTicket; | |||
protected volatile long jsapiTicketExpiresTime; | |||
private volatile String jsapiTicket; | |||
private volatile long jsapiTicketExpiresTime; | |||
protected volatile String agentJsapiTicket; | |||
protected volatile long agentJsapiTicketExpiresTime; | |||
private volatile String agentJsapiTicket; | |||
private volatile long agentJsapiTicketExpiresTime; | |||
protected volatile File tmpDirFile; | |||
private volatile File tmpDirFile; | |||
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||
protected volatile String baseApiUrl; | |||
private volatile String baseApiUrl; | |||
@Override | |||
public void setBaseApiUrl(String baseUrl) { |
@@ -1,7 +1,8 @@ | |||
package me.chanjar.weixin.cp.config; | |||
package me.chanjar.weixin.cp.config.impl; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | |||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | |||
import redis.clients.jedis.Jedis; | |||
import redis.clients.jedis.JedisPool; | |||
@@ -17,7 +18,7 @@ import java.io.File; | |||
* | |||
* @author gaigeshen | |||
*/ | |||
public class WxCpJedisConfigStorage implements WxCpConfigStorage { | |||
public class WxCpRedisConfigImpl implements WxCpConfigStorage { | |||
private static final String ACCESS_TOKEN_KEY = "WX_CP_ACCESS_TOKEN"; | |||
private static final String ACCESS_TOKEN_EXPIRES_TIME_KEY = "WX_CP_ACCESS_TOKEN_EXPIRES_TIME"; | |||
private static final String JS_API_TICKET_KEY = "WX_CP_JS_API_TICKET"; | |||
@@ -54,23 +55,23 @@ public class WxCpJedisConfigStorage implements WxCpConfigStorage { | |||
return baseApiUrl + path; | |||
} | |||
public WxCpJedisConfigStorage(JedisPool jedisPool) { | |||
public WxCpRedisConfigImpl(JedisPool jedisPool) { | |||
this.jedisPool = jedisPool; | |||
} | |||
public WxCpJedisConfigStorage(String host, int port) { | |||
public WxCpRedisConfigImpl(String host, int port) { | |||
jedisPool = new JedisPool(host, port); | |||
} | |||
public WxCpJedisConfigStorage(JedisPoolConfig poolConfig, String host, int port) { | |||
public WxCpRedisConfigImpl(JedisPoolConfig poolConfig, String host, int port) { | |||
jedisPool = new JedisPool(poolConfig, host, port); | |||
} | |||
public WxCpJedisConfigStorage(JedisPoolConfig poolConfig, String host, int port, int timeout, String password) { | |||
public WxCpRedisConfigImpl(JedisPoolConfig poolConfig, String host, int port, int timeout, String password) { | |||
jedisPool = new JedisPool(poolConfig, host, port, timeout, password); | |||
} | |||
public WxCpJedisConfigStorage(JedisPoolConfig poolConfig, String host, int port, int timeout, String password, int database) { | |||
public WxCpRedisConfigImpl(JedisPoolConfig poolConfig, String host, int port, int timeout, String password, int database) { | |||
jedisPool = new JedisPool(poolConfig, host, port, timeout, password, database); | |||
} | |||
@@ -1,44 +1,47 @@ | |||
package me.chanjar.weixin.cp.config; | |||
package me.chanjar.weixin.cp.config.impl; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; | |||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||
import java.io.File; | |||
import java.io.Serializable; | |||
/** | |||
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 | |||
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化. | |||
* | |||
* @author Daniel Qian | |||
* @author someone | |||
*/ | |||
public class WxCpTpInMemoryConfigStorage implements WxCpTpConfigStorage { | |||
protected volatile String corpId; | |||
protected volatile String corpSecret; | |||
protected volatile String suiteId; | |||
protected volatile String suiteSecret; | |||
public class WxCpTpDefaultConfigImpl implements WxCpTpConfigStorage, Serializable { | |||
private static final long serialVersionUID = 6678780920621872824L; | |||
protected volatile String token; | |||
protected volatile String suiteAccessToken; | |||
protected volatile String aesKey; | |||
protected volatile long expiresTime; | |||
private volatile String corpId; | |||
private volatile String corpSecret; | |||
protected volatile String oauth2redirectUri; | |||
private volatile String suiteId; | |||
private volatile String suiteSecret; | |||
protected volatile String httpProxyHost; | |||
protected volatile int httpProxyPort; | |||
protected volatile String httpProxyUsername; | |||
protected volatile String httpProxyPassword; | |||
private volatile String token; | |||
private volatile String suiteAccessToken; | |||
private volatile String aesKey; | |||
private volatile long expiresTime; | |||
protected volatile String suiteTicket; | |||
protected volatile long suiteTicketExpiresTime; | |||
private volatile String oauth2redirectUri; | |||
private volatile String httpProxyHost; | |||
private volatile int httpProxyPort; | |||
private volatile String httpProxyUsername; | |||
private volatile String httpProxyPassword; | |||
protected volatile File tmpDirFile; | |||
private volatile String suiteTicket; | |||
private volatile long suiteTicketExpiresTime; | |||
private volatile File tmpDirFile; | |||
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||
protected volatile String baseApiUrl; | |||
private volatile String baseApiUrl; | |||
@Override | |||
public void setBaseApiUrl(String baseUrl) { | |||
@@ -57,7 +60,7 @@ public class WxCpTpInMemoryConfigStorage implements WxCpTpConfigStorage { | |||
public String getSuiteAccessToken() { | |||
return this.suiteAccessToken; | |||
} | |||
public void setSuiteAccessToken(String suiteAccessToken) { | |||
this.suiteAccessToken = suiteAccessToken; | |||
} | |||
@@ -82,25 +85,25 @@ public class WxCpTpInMemoryConfigStorage implements WxCpTpConfigStorage { | |||
this.suiteAccessToken = suiteAccessToken; | |||
this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; | |||
} | |||
@Override | |||
public String getCorpId() { | |||
return this.corpId; | |||
} | |||
public void setCorpId(String corpId) { | |||
this.corpId = corpId; | |||
} | |||
@Override | |||
public String getCorpSecret() { | |||
return this.corpSecret; | |||
} | |||
public void setCorpSecret(String corpSecret) { | |||
this.corpSecret = corpSecret; | |||
} | |||
@Override | |||
public String getSuiteTicket() { | |||
return this.suiteTicket; |
@@ -12,7 +12,7 @@ import com.thoughtworks.xstream.XStream; | |||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; | |||
import me.chanjar.weixin.cp.config.WxCpInMemoryConfigStorage; | |||
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl; | |||
public class ApiTestModule implements Module { | |||
private final Logger log = LoggerFactory.getLogger(this.getClass()); | |||
@@ -44,7 +44,7 @@ public class ApiTestModule implements Module { | |||
} | |||
@XStreamAlias("xml") | |||
public static class WxXmlCpInMemoryConfigStorage extends WxCpInMemoryConfigStorage { | |||
public static class WxXmlCpInMemoryConfigStorage extends WxCpDefaultConfigImpl { | |||
protected String userId; | |||
@@ -6,14 +6,14 @@ import com.thoughtworks.xstream.XStream; | |||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import lombok.ToString; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
import me.chanjar.weixin.cp.config.WxCpInMemoryConfigStorage; | |||
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl; | |||
/** | |||
* @author Daniel Qian | |||
*/ | |||
@XStreamAlias("xml") | |||
@ToString | |||
public class WxCpDemoInMemoryConfigStorage extends WxCpInMemoryConfigStorage { | |||
public class WxCpDemoInMemoryConfigStorage extends WxCpDefaultConfigImpl { | |||
public static WxCpDemoInMemoryConfigStorage fromXml(InputStream is) { | |||
XStream xstream = XStreamInitializer.getInstance(); | |||
xstream.processAnnotations(WxCpDemoInMemoryConfigStorage.class); | |||
@@ -1,9 +1,10 @@ | |||
package cn.binarywang.wx.miniapp.config; | |||
package cn.binarywang.wx.miniapp.config.impl; | |||
import java.io.File; | |||
import java.util.concurrent.locks.Lock; | |||
import java.util.concurrent.locks.ReentrantLock; | |||
import cn.binarywang.wx.miniapp.config.WxMaConfig; | |||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||
@@ -13,38 +14,39 @@ import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
public class WxMaInMemoryConfig implements WxMaConfig { | |||
protected volatile String msgDataFormat; | |||
public class WxMaDefaultConfigImpl implements WxMaConfig { | |||
private volatile String msgDataFormat; | |||
protected volatile String appid; | |||
protected volatile String secret; | |||
private volatile String secret; | |||
protected volatile String token; | |||
protected volatile String accessToken; | |||
protected volatile String aesKey; | |||
protected volatile long expiresTime; | |||
private volatile String accessToken; | |||
private volatile String aesKey; | |||
private volatile long expiresTime; | |||
protected volatile String httpProxyHost; | |||
protected volatile int httpProxyPort; | |||
protected volatile String httpProxyUsername; | |||
protected volatile String httpProxyPassword; | |||
private volatile String httpProxyHost; | |||
private volatile int httpProxyPort; | |||
private volatile String httpProxyUsername; | |||
private volatile String httpProxyPassword; | |||
protected volatile String jsapiTicket; | |||
protected volatile long jsapiTicketExpiresTime; | |||
//微信卡券的ticket单独缓存 | |||
protected volatile String cardApiTicket; | |||
protected volatile long cardApiTicketExpiresTime; | |||
private volatile String jsapiTicket; | |||
private volatile long jsapiTicketExpiresTime; | |||
/** | |||
* 微信卡券的ticket单独缓存. | |||
*/ | |||
private volatile String cardApiTicket; | |||
private volatile long cardApiTicketExpiresTime; | |||
protected Lock accessTokenLock = new ReentrantLock(); | |||
protected Lock jsapiTicketLock = new ReentrantLock(); | |||
protected Lock cardApiTicketLock = new ReentrantLock(); | |||
private Lock jsapiTicketLock = new ReentrantLock(); | |||
private Lock cardApiTicketLock = new ReentrantLock(); | |||
/** | |||
* 临时文件目录 | |||
* 临时文件目录. | |||
*/ | |||
protected volatile File tmpDirFile; | |||
protected volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||
@Override | |||
public String getAccessToken() { |
@@ -1,4 +1,4 @@ | |||
package cn.binarywang.wx.miniapp.config; | |||
package cn.binarywang.wx.miniapp.config.impl; | |||
import java.io.File; | |||
import java.util.HashMap; | |||
@@ -7,6 +7,7 @@ import java.util.concurrent.TimeUnit; | |||
import java.util.concurrent.locks.Condition; | |||
import java.util.concurrent.locks.Lock; | |||
import cn.binarywang.wx.miniapp.config.WxMaConfig; | |||
import com.github.jedis.lock.JedisLock; | |||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||
@@ -17,105 +18,92 @@ import redis.clients.jedis.JedisPool; | |||
/** | |||
* 基于Redis的微信配置provider. | |||
* | |||
* | |||
* <pre> | |||
* 需要引入依赖<a href="https://github.com/abelaska/jedis-lock">jedis-lock</a>,才能使用该类。 | |||
* </pre> | |||
* | |||
* @author <a href="https://github.com/winter4666">winter</a> | |||
*/ | |||
public class WxMaInRedisConfig implements WxMaConfig { | |||
public class WxMaRedisConfigImpl implements WxMaConfig { | |||
private static final String ACCESS_TOKEN = "accessToken"; | |||
private static final String JSAPI_TICKET = "jsapiTicket"; | |||
private static final String CARD_API_TICKET = "cardApiTicket"; | |||
private static final String HASH_VALUE_FIELD = "value"; | |||
private static final String HASH_EXPIRE_FIELD = "expire"; | |||
protected JedisPool jedisPool; | |||
private JedisPool jedisPool; | |||
/** | |||
* 微信小程序唯一id,用于拼接存储到redis时的key,防止key重复 | |||
* 微信小程序唯一id,用于拼接存储到redis时的key,防止key重复. | |||
*/ | |||
protected String maId; | |||
protected volatile String msgDataFormat; | |||
private String maId; | |||
private volatile String msgDataFormat; | |||
protected volatile String appid; | |||
protected volatile String secret; | |||
private volatile String secret; | |||
protected volatile String token; | |||
protected volatile String aesKey; | |||
private volatile String aesKey; | |||
protected volatile String httpProxyHost; | |||
protected volatile int httpProxyPort; | |||
protected volatile String httpProxyUsername; | |||
protected volatile String httpProxyPassword; | |||
private volatile String httpProxyHost; | |||
private volatile int httpProxyPort; | |||
private volatile String httpProxyUsername; | |||
private volatile String httpProxyPassword; | |||
protected Lock accessTokenLock; | |||
protected Lock jsapiTicketLock; | |||
protected Lock cardApiTicketLock; | |||
private Lock accessTokenLock; | |||
private Lock jsapiTicketLock; | |||
private Lock cardApiTicketLock; | |||
/** | |||
* 临时文件目录 | |||
* 临时文件目录. | |||
*/ | |||
protected volatile File tmpDirFile; | |||
protected volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||
private String getRedisKey(String key) { | |||
StringBuilder redisKey = new StringBuilder("maConfig:"); | |||
if(maId == null) { | |||
return redisKey.append(key).toString(); | |||
} else { | |||
return redisKey.append(maId).append(":").append(key).toString(); | |||
} | |||
} | |||
StringBuilder redisKey = new StringBuilder("maConfig:"); | |||
if (maId == null) { | |||
return redisKey.append(key).toString(); | |||
} else { | |||
return redisKey.append(maId).append(":").append(key).toString(); | |||
} | |||
} | |||
private String getValueFromRedis(String key) { | |||
Jedis jedis = jedisPool.getResource(); | |||
try { | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
return jedis.hget(getRedisKey(key), HASH_VALUE_FIELD); | |||
} finally { | |||
jedis.close(); | |||
} | |||
} | |||
} | |||
private void setValueToRedis(String key, long expiresTime, String value) { | |||
Jedis jedis = jedisPool.getResource(); | |||
try { | |||
Map<String, String> hash = new HashMap<String, String>(); | |||
hash.put(HASH_VALUE_FIELD, value); | |||
hash.put(HASH_EXPIRE_FIELD, String.valueOf(expiresTime)); | |||
jedis.hmset(getRedisKey(key), hash); | |||
} finally { | |||
jedis.close(); | |||
} | |||
} | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
Map<String, String> hash = new HashMap<String, String>(); | |||
hash.put(HASH_VALUE_FIELD, value); | |||
hash.put(HASH_EXPIRE_FIELD, String.valueOf(expiresTime)); | |||
jedis.hmset(getRedisKey(key), hash); | |||
} | |||
} | |||
private long getExpireFromRedis(String key) { | |||
Jedis jedis = jedisPool.getResource(); | |||
try { | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
String expire = jedis.hget(getRedisKey(key), HASH_EXPIRE_FIELD); | |||
return expire == null ? 0 : Long.valueOf(expire); | |||
} finally { | |||
jedis.close(); | |||
} | |||
return expire == null ? 0 : Long.parseLong(expire); | |||
} | |||
} | |||
private void setExpire(String key, long expiresTime) { | |||
Jedis jedis = jedisPool.getResource(); | |||
try { | |||
jedis.hset(getRedisKey(key), HASH_EXPIRE_FIELD, String.valueOf(expiresTime)); | |||
} finally { | |||
jedis.close(); | |||
} | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
jedis.hset(getRedisKey(key), HASH_EXPIRE_FIELD, String.valueOf(expiresTime)); | |||
} | |||
} | |||
public void setJedisPool(JedisPool jedisPool) { | |||
this.jedisPool = jedisPool; | |||
this.jedisPool = jedisPool; | |||
} | |||
public void setMaId(String maId) { | |||
this.maId = maId; | |||
this.maId = maId; | |||
} | |||
@Override | |||
@@ -125,19 +113,19 @@ public class WxMaInRedisConfig implements WxMaConfig { | |||
@Override | |||
public Lock getAccessTokenLock() { | |||
if(accessTokenLock == null) { | |||
synchronized (this) { | |||
if(accessTokenLock == null) { | |||
accessTokenLock = new DistributedLock(getRedisKey("accessTokenLock")); | |||
} | |||
} | |||
} | |||
if (accessTokenLock == null) { | |||
synchronized (this) { | |||
if (accessTokenLock == null) { | |||
accessTokenLock = new DistributedLock(getRedisKey("accessTokenLock")); | |||
} | |||
} | |||
} | |||
return accessTokenLock; | |||
} | |||
@Override | |||
public boolean isAccessTokenExpired() { | |||
return System.currentTimeMillis() > getExpireFromRedis(ACCESS_TOKEN); | |||
return System.currentTimeMillis() > getExpireFromRedis(ACCESS_TOKEN); | |||
} | |||
@Override | |||
@@ -147,7 +135,7 @@ public class WxMaInRedisConfig implements WxMaConfig { | |||
@Override | |||
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { | |||
setValueToRedis(ACCESS_TOKEN, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, accessToken); | |||
setValueToRedis(ACCESS_TOKEN, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, accessToken); | |||
} | |||
@Override | |||
@@ -157,30 +145,30 @@ public class WxMaInRedisConfig implements WxMaConfig { | |||
@Override | |||
public Lock getJsapiTicketLock() { | |||
if(jsapiTicketLock == null) { | |||
synchronized (this) { | |||
if(jsapiTicketLock == null) { | |||
jsapiTicketLock = new DistributedLock(getRedisKey("jsapiTicketLock")); | |||
} | |||
} | |||
} | |||
if (jsapiTicketLock == null) { | |||
synchronized (this) { | |||
if (jsapiTicketLock == null) { | |||
jsapiTicketLock = new DistributedLock(getRedisKey("jsapiTicketLock")); | |||
} | |||
} | |||
} | |||
return jsapiTicketLock; | |||
} | |||
@Override | |||
public boolean isJsapiTicketExpired() { | |||
return System.currentTimeMillis() > getExpireFromRedis(JSAPI_TICKET); | |||
return System.currentTimeMillis() > getExpireFromRedis(JSAPI_TICKET); | |||
} | |||
@Override | |||
public void expireJsapiTicket() { | |||
setExpire(JSAPI_TICKET, 0); | |||
setExpire(JSAPI_TICKET, 0); | |||
} | |||
@Override | |||
public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { | |||
// 预留200秒的时间 | |||
setValueToRedis(JSAPI_TICKET, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, jsapiTicket); | |||
// 预留200秒的时间 | |||
setValueToRedis(JSAPI_TICKET, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, jsapiTicket); | |||
} | |||
@@ -191,34 +179,34 @@ public class WxMaInRedisConfig implements WxMaConfig { | |||
@Override | |||
public Lock getCardApiTicketLock() { | |||
if(cardApiTicketLock == null) { | |||
synchronized (this) { | |||
if(cardApiTicketLock == null) { | |||
cardApiTicketLock = new DistributedLock(getRedisKey("cardApiTicketLock")); | |||
} | |||
} | |||
} | |||
if (cardApiTicketLock == null) { | |||
synchronized (this) { | |||
if (cardApiTicketLock == null) { | |||
cardApiTicketLock = new DistributedLock(getRedisKey("cardApiTicketLock")); | |||
} | |||
} | |||
} | |||
return cardApiTicketLock; | |||
} | |||
@Override | |||
public boolean isCardApiTicketExpired() { | |||
return System.currentTimeMillis() > getExpireFromRedis(CARD_API_TICKET); | |||
return System.currentTimeMillis() > getExpireFromRedis(CARD_API_TICKET); | |||
} | |||
@Override | |||
public void expireCardApiTicket() { | |||
setExpire(CARD_API_TICKET, 0); | |||
setExpire(CARD_API_TICKET, 0); | |||
} | |||
@Override | |||
public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) { | |||
setValueToRedis(CARD_API_TICKET, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, cardApiTicket); | |||
setValueToRedis(CARD_API_TICKET, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, cardApiTicket); | |||
} | |||
@Override | |||
public void expireAccessToken() { | |||
setExpire(ACCESS_TOKEN, 0); | |||
setExpire(ACCESS_TOKEN, 0); | |||
} | |||
@Override | |||
@@ -241,7 +229,7 @@ public class WxMaInRedisConfig implements WxMaConfig { | |||
@Override | |||
public long getExpiresTime() { | |||
return getExpireFromRedis(ACCESS_TOKEN); | |||
return getExpireFromRedis(ACCESS_TOKEN); | |||
} | |||
@Override | |||
@@ -325,80 +313,65 @@ public class WxMaInRedisConfig implements WxMaConfig { | |||
public void setAppid(String appid) { | |||
this.appid = appid; | |||
} | |||
/** | |||
* 基于redis的简单分布式锁 | |||
* 基于redis的简单分布式锁. | |||
*/ | |||
private class DistributedLock implements Lock { | |||
private JedisLock lock; | |||
private DistributedLock(String key) { | |||
this.lock = new JedisLock(getRedisKey(key)); | |||
} | |||
@Override | |||
public void lock() { | |||
Jedis jedis = jedisPool.getResource(); | |||
try { | |||
if(!lock.acquire(jedis)) { | |||
throw new RuntimeException("acquire timeouted"); | |||
} | |||
} catch (InterruptedException e) { | |||
throw new RuntimeException("lock failed",e); | |||
} finally { | |||
jedis.close(); | |||
} | |||
} | |||
@Override | |||
public void lockInterruptibly() throws InterruptedException { | |||
Jedis jedis = jedisPool.getResource(); | |||
try { | |||
if(!lock.acquire(jedis)) { | |||
throw new RuntimeException("acquire timeouted"); | |||
} | |||
} finally { | |||
jedis.close(); | |||
} | |||
} | |||
@Override | |||
public boolean tryLock() { | |||
Jedis jedis = jedisPool.getResource(); | |||
try { | |||
return lock.acquire(jedis); | |||
} catch (InterruptedException e) { | |||
throw new RuntimeException("lock failed",e); | |||
} finally { | |||
jedis.close(); | |||
} | |||
} | |||
@Override | |||
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { | |||
Jedis jedis = jedisPool.getResource(); | |||
try { | |||
return lock.acquire(jedis); | |||
} finally { | |||
jedis.close(); | |||
} | |||
} | |||
@Override | |||
public void unlock() { | |||
Jedis jedis = jedisPool.getResource(); | |||
try { | |||
lock.release(jedis); | |||
} finally { | |||
jedis.close(); | |||
} | |||
} | |||
@Override | |||
public Condition newCondition() { | |||
throw new RuntimeException("unsupported method"); | |||
} | |||
private JedisLock lock; | |||
private DistributedLock(String key) { | |||
this.lock = new JedisLock(getRedisKey(key)); | |||
} | |||
@Override | |||
public void lock() { | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
if (!lock.acquire(jedis)) { | |||
throw new RuntimeException("acquire timeouted"); | |||
} | |||
} catch (InterruptedException e) { | |||
throw new RuntimeException("lock failed", e); | |||
} | |||
} | |||
@Override | |||
public void lockInterruptibly() throws InterruptedException { | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
if (!lock.acquire(jedis)) { | |||
throw new RuntimeException("acquire timeouted"); | |||
} | |||
} | |||
} | |||
@Override | |||
public boolean tryLock() { | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
return lock.acquire(jedis); | |||
} catch (InterruptedException e) { | |||
throw new RuntimeException("lock failed", e); | |||
} | |||
} | |||
@Override | |||
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
return lock.acquire(jedis); | |||
} | |||
} | |||
@Override | |||
public void unlock() { | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
lock.release(jedis); | |||
} | |||
} | |||
@Override | |||
public Condition newCondition() { | |||
throw new RuntimeException("unsupported method"); | |||
} | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
package cn.binarywang.wx.miniapp.test; | |||
import cn.binarywang.wx.miniapp.config.WxMaInMemoryConfig; | |||
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; | |||
import com.thoughtworks.xstream.XStream; | |||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
@@ -13,7 +13,7 @@ import java.util.concurrent.locks.Lock; | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
@XStreamAlias("xml") | |||
public class TestConfig extends WxMaInMemoryConfig { | |||
public class TestConfig extends WxMaDefaultConfigImpl { | |||
private String openid; | |||
private String kfAccount; | |||
@@ -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; | |||
@@ -15,7 +15,7 @@ import lombok.extern.slf4j.Slf4j; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.util.XmlUtils; | |||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.util.crypto.WxMpCryptUtil; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
import me.chanjar.weixin.mp.util.xml.XStreamTransformer; | |||
@@ -527,10 +527,10 @@ public class WxMpXmlMessage implements Serializable { | |||
@XStreamAlias("DeviceID") | |||
@XStreamConverter(value = XStreamCDataConverter.class) | |||
private String deviceId; | |||
/** | |||
* 微信客户端生成的session id,用于request和response对应, | |||
* 因此响应中该字段第三方需要原封不变的带回 | |||
* 因此响应中该字段第三方需要原封不变的带回 | |||
*/ | |||
@XStreamAlias("SessionID") | |||
@XStreamConverter(value = XStreamCDataConverter.class) | |||
@@ -4,7 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import com.thoughtworks.xstream.annotations.XStreamConverter; | |||
import lombok.Data; | |||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.builder.outxml.*; | |||
import me.chanjar.weixin.mp.util.crypto.WxMpCryptUtil; | |||
import me.chanjar.weixin.mp.util.xml.XStreamTransformer; | |||
@@ -79,7 +79,7 @@ public abstract class WxMpXmlOutMessage implements Serializable { | |||
public static TransferCustomerServiceBuilder TRANSFER_CUSTOMER_SERVICE() { | |||
return new TransferCustomerServiceBuilder(); | |||
} | |||
/** | |||
* 获得设备消息builder | |||
*/ | |||
@@ -1,4 +1,4 @@ | |||
package me.chanjar.weixin.mp.api; | |||
package me.chanjar.weixin.mp.config; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; |
@@ -1,4 +1,4 @@ | |||
package me.chanjar.weixin.mp.api; | |||
package me.chanjar.weixin.mp.config.impl; | |||
import java.io.File; | |||
import java.io.Serializable; | |||
@@ -8,6 +8,7 @@ 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.config.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.bean.WxMpHostConfig; | |||
import me.chanjar.weixin.mp.enums.TicketType; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
@@ -18,7 +19,7 @@ import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
* @author chanjarster | |||
*/ | |||
@Data | |||
public class WxMpInMemoryConfigStorage implements WxMpConfigStorage, Serializable { | |||
public class WxMpDefaultConfigImpl implements WxMpConfigStorage, Serializable { | |||
private static final long serialVersionUID = -6646519023303395185L; | |||
protected volatile String appId; |
@@ -1,4 +1,4 @@ | |||
package me.chanjar.weixin.mp.api; | |||
package me.chanjar.weixin.mp.config.impl; | |||
import me.chanjar.weixin.mp.enums.TicketType; | |||
import redis.clients.jedis.Jedis; | |||
@@ -15,17 +15,17 @@ import redis.clients.jedis.JedisPool; | |||
* @author nickwong | |||
*/ | |||
@SuppressWarnings("hiding") | |||
public class WxMpInRedisConfigStorage extends WxMpInMemoryConfigStorage { | |||
public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl { | |||
private static final String ACCESS_TOKEN_KEY = "wx:access_token:"; | |||
/** | |||
* 使用连接池保证线程安全. | |||
*/ | |||
protected final JedisPool jedisPool; | |||
private final JedisPool jedisPool; | |||
private String accessTokenKey; | |||
public WxMpInRedisConfigStorage(JedisPool jedisPool) { | |||
public WxMpRedisConfigImpl(JedisPool jedisPool) { | |||
this.jedisPool = jedisPool; | |||
} | |||
@@ -1,7 +1,7 @@ | |||
package me.chanjar.weixin.mp.enums; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import static me.chanjar.weixin.mp.bean.WxMpHostConfig.*; | |||
@@ -17,7 +17,7 @@ | |||
*/ | |||
package me.chanjar.weixin.mp.util.crypto; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import org.apache.commons.codec.binary.Base64; | |||
public class WxMpCryptUtil extends me.chanjar.weixin.common.util.crypto.WxCryptUtil { | |||
@@ -7,7 +7,7 @@ import org.testng.annotations.*; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
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.test.ApiTestModule; | |||
import me.chanjar.weixin.mp.api.test.TestConfigStorage; | |||
@@ -12,7 +12,7 @@ import com.google.inject.Binder; | |||
import com.google.inject.Module; | |||
import com.thoughtworks.xstream.XStream; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
public class ApiTestModule implements Module { | |||
@@ -1,13 +1,13 @@ | |||
package me.chanjar.weixin.mp.api.test; | |||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; | |||
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import java.util.concurrent.locks.Lock; | |||
@XStreamAlias("xml") | |||
public class TestConfigStorage extends WxMpInMemoryConfigStorage { | |||
public class TestConfigStorage extends WxMpDefaultConfigImpl { | |||
private String openid; | |||
private String kfAccount; | |||
@@ -6,13 +6,13 @@ import java.util.concurrent.locks.ReentrantLock; | |||
import com.thoughtworks.xstream.XStream; | |||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; | |||
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; | |||
/** | |||
* @author Daniel Qian | |||
*/ | |||
@XStreamAlias("xml") | |||
class WxMpDemoInMemoryConfigStorage extends WxMpInMemoryConfigStorage { | |||
class WxMpDemoInMemoryConfigStorage extends WxMpDefaultConfigImpl { | |||
private static final long serialVersionUID = -3706236839197109704L; | |||
public static WxMpDemoInMemoryConfigStorage fromXml(InputStream is) { | |||
@@ -1,7 +1,7 @@ | |||
package me.chanjar.weixin.mp.demo; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.api.WxMpMessageHandler; | |||
import me.chanjar.weixin.mp.api.WxMpMessageRouter; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
@@ -1,6 +1,6 @@ | |||
package me.chanjar.weixin.mp.demo; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.api.WxMpMessageRouter; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
@@ -2,7 +2,7 @@ package me.chanjar.weixin.open.api; | |||
import cn.binarywang.wx.miniapp.config.WxMaConfig; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; | |||
import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; | |||
@@ -10,7 +10,7 @@ import java.util.concurrent.locks.ReentrantLock; | |||
import cn.binarywang.wx.miniapp.config.WxMaConfig; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.bean.WxMpHostConfig; | |||
import me.chanjar.weixin.mp.enums.TicketType; | |||
import me.chanjar.weixin.open.api.WxOpenConfigStorage; | |||
@@ -1,7 +1,7 @@ | |||
package me.chanjar.weixin.open.api.impl; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | |||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | |||
import me.chanjar.weixin.open.api.WxOpenComponentService; | |||
@@ -6,7 +6,6 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
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.open.api.WxOpenConfigStorage; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||