| @@ -1,6 +1,6 @@ | |||||
| package com.binarywang.spring.starter.wxjava.mp; | 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.WxMpService; | ||||
| import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| @@ -1,8 +1,8 @@ | |||||
| package com.binarywang.spring.starter.wxjava.mp; | 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.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||||
| import org.springframework.context.annotation.Bean; | import org.springframework.context.annotation.Bean; | ||||
| @@ -34,23 +34,23 @@ public class WxMpStorageAutoConfiguration { | |||||
| return getWxMpInMemoryConfigStorage(); | return getWxMpInMemoryConfigStorage(); | ||||
| } | } | ||||
| private WxMpInMemoryConfigStorage getWxMpInMemoryConfigStorage() { | |||||
| WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage(); | |||||
| private WxMpDefaultConfigImpl getWxMpInMemoryConfigStorage() { | |||||
| WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl(); | |||||
| setWxMpInfo(config); | setWxMpInfo(config); | ||||
| return config; | return config; | ||||
| } | } | ||||
| private WxMpInRedisConfigStorage getWxMpInRedisConfigStorage() { | |||||
| private WxMpRedisConfigImpl getWxMpInRedisConfigStorage() { | |||||
| JedisPool poolToUse = jedisPool; | JedisPool poolToUse = jedisPool; | ||||
| if (poolToUse == null) { | if (poolToUse == null) { | ||||
| poolToUse = getJedisPool(); | poolToUse = getJedisPool(); | ||||
| } | } | ||||
| WxMpInRedisConfigStorage config = new WxMpInRedisConfigStorage(poolToUse); | |||||
| WxMpRedisConfigImpl config = new WxMpRedisConfigImpl(poolToUse); | |||||
| setWxMpInfo(config); | setWxMpInfo(config); | ||||
| return config; | return config; | ||||
| } | } | ||||
| private void setWxMpInfo(WxMpInMemoryConfigStorage config) { | |||||
| private void setWxMpInfo(WxMpDefaultConfigImpl config) { | |||||
| config.setAppId(properties.getAppId()); | config.setAppId(properties.getAppId()); | ||||
| config.setSecret(properties.getSecret()); | config.setSecret(properties.getSecret()); | ||||
| config.setToken(properties.getToken()); | config.setToken(properties.getToken()); | ||||
| @@ -14,7 +14,6 @@ public interface WxCpTpConfigStorage { | |||||
| /** | /** | ||||
| * 设置企业微信服务器 baseUrl. | * 设置企业微信服务器 baseUrl. | ||||
| * | |||||
| * 默认值是 https://qyapi.weixin.qq.com , 如果使用默认值,则不需要调用 setBaseApiUrl | * 默认值是 https://qyapi.weixin.qq.com , 如果使用默认值,则不需要调用 setBaseApiUrl | ||||
| * | * | ||||
| * @param baseUrl 企业微信服务器 Url | * @param baseUrl 企业微信服务器 Url | ||||
| @@ -23,7 +22,6 @@ public interface WxCpTpConfigStorage { | |||||
| /** | /** | ||||
| * 读取企业微信 API Url. | * 读取企业微信 API Url. | ||||
| * | |||||
| * 支持私有化企业微信服务器. | * 支持私有化企业微信服务器. | ||||
| */ | */ | ||||
| String getApiUrl(String path); | String getApiUrl(String path); | ||||
| @@ -33,7 +31,7 @@ public interface WxCpTpConfigStorage { | |||||
| boolean isSuiteAccessTokenExpired(); | boolean isSuiteAccessTokenExpired(); | ||||
| /** | /** | ||||
| * 强制将suite access token过期掉 | |||||
| * 强制将suite access token过期掉. | |||||
| */ | */ | ||||
| void expireSuiteAccessToken(); | void expireSuiteAccessToken(); | ||||
| @@ -46,15 +44,15 @@ public interface WxCpTpConfigStorage { | |||||
| boolean isSuiteTicketExpired(); | boolean isSuiteTicketExpired(); | ||||
| /** | /** | ||||
| * 强制将suite ticket过期掉 | |||||
| * 强制将suite ticket过期掉. | |||||
| */ | */ | ||||
| void expireSuiteTicket(); | void expireSuiteTicket(); | ||||
| /** | /** | ||||
| * 应该是线程安全的 | |||||
| * 应该是线程安全的. | |||||
| */ | */ | ||||
| void updateSuiteTicket(String suiteTicket, int expiresInSeconds); | void updateSuiteTicket(String suiteTicket, int expiresInSeconds); | ||||
| String getCorpId(); | String getCorpId(); | ||||
| String getCorpSecret(); | String getCorpSecret(); | ||||
| @@ -80,7 +78,7 @@ public interface WxCpTpConfigStorage { | |||||
| File getTmpDirFile(); | File getTmpDirFile(); | ||||
| /** | /** | ||||
| * http client builder | |||||
| * http client builder. | |||||
| * | * | ||||
| * @return ApacheHttpClientBuilder | * @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.bean.WxAccessToken; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | 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.constant.WxCpApiPathConsts; | ||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.Serializable; | |||||
| /** | /** | ||||
| * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 | |||||
| * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化. | |||||
| * | * | ||||
| * @author Daniel Qian | * @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 accessToken; | ||||
| protected volatile String aesKey; | |||||
| private volatile String aesKey; | |||||
| protected volatile Integer agentId; | 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; | private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | ||||
| protected volatile String baseApiUrl; | |||||
| private volatile String baseApiUrl; | |||||
| @Override | @Override | ||||
| public void setBaseApiUrl(String baseUrl) { | 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.bean.WxAccessToken; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | 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.constant.WxCpApiPathConsts; | ||||
| import redis.clients.jedis.Jedis; | import redis.clients.jedis.Jedis; | ||||
| import redis.clients.jedis.JedisPool; | import redis.clients.jedis.JedisPool; | ||||
| @@ -17,7 +18,7 @@ import java.io.File; | |||||
| * | * | ||||
| * @author gaigeshen | * @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_KEY = "WX_CP_ACCESS_TOKEN"; | ||||
| private static final String ACCESS_TOKEN_EXPIRES_TIME_KEY = "WX_CP_ACCESS_TOKEN_EXPIRES_TIME"; | 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"; | 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; | return baseApiUrl + path; | ||||
| } | } | ||||
| public WxCpJedisConfigStorage(JedisPool jedisPool) { | |||||
| public WxCpRedisConfigImpl(JedisPool jedisPool) { | |||||
| this.jedisPool = jedisPool; | this.jedisPool = jedisPool; | ||||
| } | } | ||||
| public WxCpJedisConfigStorage(String host, int port) { | |||||
| public WxCpRedisConfigImpl(String host, int port) { | |||||
| jedisPool = new JedisPool(host, 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); | 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); | 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); | 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.bean.WxAccessToken; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | 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 me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
| import java.io.File; | 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; | private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | ||||
| protected volatile String baseApiUrl; | |||||
| private volatile String baseApiUrl; | |||||
| @Override | @Override | ||||
| public void setBaseApiUrl(String baseUrl) { | public void setBaseApiUrl(String baseUrl) { | ||||
| @@ -57,7 +60,7 @@ public class WxCpTpInMemoryConfigStorage implements WxCpTpConfigStorage { | |||||
| public String getSuiteAccessToken() { | public String getSuiteAccessToken() { | ||||
| return this.suiteAccessToken; | return this.suiteAccessToken; | ||||
| } | } | ||||
| public void setSuiteAccessToken(String suiteAccessToken) { | public void setSuiteAccessToken(String suiteAccessToken) { | ||||
| this.suiteAccessToken = suiteAccessToken; | this.suiteAccessToken = suiteAccessToken; | ||||
| } | } | ||||
| @@ -82,25 +85,25 @@ public class WxCpTpInMemoryConfigStorage implements WxCpTpConfigStorage { | |||||
| this.suiteAccessToken = suiteAccessToken; | this.suiteAccessToken = suiteAccessToken; | ||||
| this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; | this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; | ||||
| } | } | ||||
| @Override | @Override | ||||
| public String getCorpId() { | public String getCorpId() { | ||||
| return this.corpId; | return this.corpId; | ||||
| } | } | ||||
| public void setCorpId(String corpId) { | public void setCorpId(String corpId) { | ||||
| this.corpId = corpId; | this.corpId = corpId; | ||||
| } | } | ||||
| @Override | @Override | ||||
| public String getCorpSecret() { | public String getCorpSecret() { | ||||
| return this.corpSecret; | return this.corpSecret; | ||||
| } | } | ||||
| public void setCorpSecret(String corpSecret) { | public void setCorpSecret(String corpSecret) { | ||||
| this.corpSecret = corpSecret; | this.corpSecret = corpSecret; | ||||
| } | } | ||||
| @Override | @Override | ||||
| public String getSuiteTicket() { | public String getSuiteTicket() { | ||||
| return this.suiteTicket; | return this.suiteTicket; | ||||
| @@ -12,7 +12,7 @@ import com.thoughtworks.xstream.XStream; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import me.chanjar.weixin.common.util.xml.XStreamInitializer; | import me.chanjar.weixin.common.util.xml.XStreamInitializer; | ||||
| import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; | 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 { | public class ApiTestModule implements Module { | ||||
| private final Logger log = LoggerFactory.getLogger(this.getClass()); | private final Logger log = LoggerFactory.getLogger(this.getClass()); | ||||
| @@ -44,7 +44,7 @@ public class ApiTestModule implements Module { | |||||
| } | } | ||||
| @XStreamAlias("xml") | @XStreamAlias("xml") | ||||
| public static class WxXmlCpInMemoryConfigStorage extends WxCpInMemoryConfigStorage { | |||||
| public static class WxXmlCpInMemoryConfigStorage extends WxCpDefaultConfigImpl { | |||||
| protected String userId; | protected String userId; | ||||
| @@ -6,14 +6,14 @@ import com.thoughtworks.xstream.XStream; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import lombok.ToString; | import lombok.ToString; | ||||
| import me.chanjar.weixin.common.util.xml.XStreamInitializer; | 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 | * @author Daniel Qian | ||||
| */ | */ | ||||
| @XStreamAlias("xml") | @XStreamAlias("xml") | ||||
| @ToString | @ToString | ||||
| public class WxCpDemoInMemoryConfigStorage extends WxCpInMemoryConfigStorage { | |||||
| public class WxCpDemoInMemoryConfigStorage extends WxCpDefaultConfigImpl { | |||||
| public static WxCpDemoInMemoryConfigStorage fromXml(InputStream is) { | public static WxCpDemoInMemoryConfigStorage fromXml(InputStream is) { | ||||
| XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
| xstream.processAnnotations(WxCpDemoInMemoryConfigStorage.class); | 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.io.File; | ||||
| import java.util.concurrent.locks.Lock; | import java.util.concurrent.locks.Lock; | ||||
| import java.util.concurrent.locks.ReentrantLock; | import java.util.concurrent.locks.ReentrantLock; | ||||
| import cn.binarywang.wx.miniapp.config.WxMaConfig; | |||||
| import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
| import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | 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> | * @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 appid; | ||||
| protected volatile String secret; | |||||
| private volatile String secret; | |||||
| protected volatile String token; | 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 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 File tmpDirFile; | ||||
| protected volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||||
| private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||||
| @Override | @Override | ||||
| public String getAccessToken() { | 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.io.File; | ||||
| import java.util.HashMap; | import java.util.HashMap; | ||||
| @@ -7,6 +7,7 @@ import java.util.concurrent.TimeUnit; | |||||
| import java.util.concurrent.locks.Condition; | import java.util.concurrent.locks.Condition; | ||||
| import java.util.concurrent.locks.Lock; | import java.util.concurrent.locks.Lock; | ||||
| import cn.binarywang.wx.miniapp.config.WxMaConfig; | |||||
| import com.github.jedis.lock.JedisLock; | import com.github.jedis.lock.JedisLock; | ||||
| import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
| @@ -17,105 +18,92 @@ import redis.clients.jedis.JedisPool; | |||||
| /** | /** | ||||
| * 基于Redis的微信配置provider. | * 基于Redis的微信配置provider. | ||||
| * | |||||
| * | |||||
| * <pre> | * <pre> | ||||
| * 需要引入依赖<a href="https://github.com/abelaska/jedis-lock">jedis-lock</a>,才能使用该类。 | * 需要引入依赖<a href="https://github.com/abelaska/jedis-lock">jedis-lock</a>,才能使用该类。 | ||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @author <a href="https://github.com/winter4666">winter</a> | * @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 ACCESS_TOKEN = "accessToken"; | ||||
| private static final String JSAPI_TICKET = "jsapiTicket"; | private static final String JSAPI_TICKET = "jsapiTicket"; | ||||
| private static final String CARD_API_TICKET = "cardApiTicket"; | private static final String CARD_API_TICKET = "cardApiTicket"; | ||||
| private static final String HASH_VALUE_FIELD = "value"; | private static final String HASH_VALUE_FIELD = "value"; | ||||
| private static final String HASH_EXPIRE_FIELD = "expire"; | 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 appid; | ||||
| protected volatile String secret; | |||||
| private volatile String secret; | |||||
| protected volatile String token; | 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 File tmpDirFile; | ||||
| protected volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||||
| private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||||
| private String getRedisKey(String key) { | 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) { | private String getValueFromRedis(String key) { | ||||
| Jedis jedis = jedisPool.getResource(); | |||||
| try { | |||||
| try (Jedis jedis = jedisPool.getResource()) { | |||||
| return jedis.hget(getRedisKey(key), HASH_VALUE_FIELD); | return jedis.hget(getRedisKey(key), HASH_VALUE_FIELD); | ||||
| } finally { | |||||
| jedis.close(); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| private void setValueToRedis(String key, long expiresTime, String value) { | 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) { | private long getExpireFromRedis(String key) { | ||||
| Jedis jedis = jedisPool.getResource(); | |||||
| try { | |||||
| try (Jedis jedis = jedisPool.getResource()) { | |||||
| String expire = jedis.hget(getRedisKey(key), HASH_EXPIRE_FIELD); | 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) { | 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) { | public void setJedisPool(JedisPool jedisPool) { | ||||
| this.jedisPool = jedisPool; | |||||
| this.jedisPool = jedisPool; | |||||
| } | } | ||||
| public void setMaId(String maId) { | public void setMaId(String maId) { | ||||
| this.maId = maId; | |||||
| this.maId = maId; | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -125,19 +113,19 @@ public class WxMaInRedisConfig implements WxMaConfig { | |||||
| @Override | @Override | ||||
| public Lock getAccessTokenLock() { | 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; | return accessTokenLock; | ||||
| } | } | ||||
| @Override | @Override | ||||
| public boolean isAccessTokenExpired() { | public boolean isAccessTokenExpired() { | ||||
| return System.currentTimeMillis() > getExpireFromRedis(ACCESS_TOKEN); | |||||
| return System.currentTimeMillis() > getExpireFromRedis(ACCESS_TOKEN); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -147,7 +135,7 @@ public class WxMaInRedisConfig implements WxMaConfig { | |||||
| @Override | @Override | ||||
| public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { | 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 | @Override | ||||
| @@ -157,30 +145,30 @@ public class WxMaInRedisConfig implements WxMaConfig { | |||||
| @Override | @Override | ||||
| public Lock getJsapiTicketLock() { | 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; | return jsapiTicketLock; | ||||
| } | } | ||||
| @Override | @Override | ||||
| public boolean isJsapiTicketExpired() { | public boolean isJsapiTicketExpired() { | ||||
| return System.currentTimeMillis() > getExpireFromRedis(JSAPI_TICKET); | |||||
| return System.currentTimeMillis() > getExpireFromRedis(JSAPI_TICKET); | |||||
| } | } | ||||
| @Override | @Override | ||||
| public void expireJsapiTicket() { | public void expireJsapiTicket() { | ||||
| setExpire(JSAPI_TICKET, 0); | |||||
| setExpire(JSAPI_TICKET, 0); | |||||
| } | } | ||||
| @Override | @Override | ||||
| public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { | 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 | @Override | ||||
| public Lock getCardApiTicketLock() { | 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; | return cardApiTicketLock; | ||||
| } | } | ||||
| @Override | @Override | ||||
| public boolean isCardApiTicketExpired() { | public boolean isCardApiTicketExpired() { | ||||
| return System.currentTimeMillis() > getExpireFromRedis(CARD_API_TICKET); | |||||
| return System.currentTimeMillis() > getExpireFromRedis(CARD_API_TICKET); | |||||
| } | } | ||||
| @Override | @Override | ||||
| public void expireCardApiTicket() { | public void expireCardApiTicket() { | ||||
| setExpire(CARD_API_TICKET, 0); | |||||
| setExpire(CARD_API_TICKET, 0); | |||||
| } | } | ||||
| @Override | @Override | ||||
| public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) { | 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 | @Override | ||||
| public void expireAccessToken() { | public void expireAccessToken() { | ||||
| setExpire(ACCESS_TOKEN, 0); | |||||
| setExpire(ACCESS_TOKEN, 0); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -241,7 +229,7 @@ public class WxMaInRedisConfig implements WxMaConfig { | |||||
| @Override | @Override | ||||
| public long getExpiresTime() { | public long getExpiresTime() { | ||||
| return getExpireFromRedis(ACCESS_TOKEN); | |||||
| return getExpireFromRedis(ACCESS_TOKEN); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -325,80 +313,65 @@ public class WxMaInRedisConfig implements WxMaConfig { | |||||
| public void setAppid(String appid) { | public void setAppid(String appid) { | ||||
| this.appid = appid; | this.appid = appid; | ||||
| } | } | ||||
| /** | /** | ||||
| * 基于redis的简单分布式锁 | |||||
| * 基于redis的简单分布式锁. | |||||
| */ | */ | ||||
| private class DistributedLock implements Lock { | 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; | 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.XStream; | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import me.chanjar.weixin.common.util.xml.XStreamInitializer; | 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> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
| */ | */ | ||||
| @XStreamAlias("xml") | @XStreamAlias("xml") | ||||
| public class TestConfig extends WxMaInMemoryConfig { | |||||
| public class TestConfig extends WxMaDefaultConfigImpl { | |||||
| private String openid; | private String openid; | ||||
| private String kfAccount; | 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.WxMpOAuth2AccessToken; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; | import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpUser; | 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.TicketType; | ||||
| import me.chanjar.weixin.mp.enums.WxMpApiUrl; | 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.WxMpOAuth2AccessToken; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; | import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpUser; | 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.TicketType; | ||||
| import me.chanjar.weixin.mp.enums.WxMpApiUrl; | import me.chanjar.weixin.mp.enums.WxMpApiUrl; | ||||
| import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; | 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.HttpType; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | ||||
| import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; | 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.HttpHost; | ||||
| import org.apache.http.client.config.RequestConfig; | import org.apache.http.client.config.RequestConfig; | ||||
| import org.apache.http.client.methods.CloseableHttpResponse; | 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.WxError; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.HttpType; | 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; | 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.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.HttpType; | import me.chanjar.weixin.common.util.http.HttpType; | ||||
| import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; | 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 okhttp3.*; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| @@ -3,7 +3,7 @@ package me.chanjar.weixin.mp.api.impl; | |||||
| import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.URIUtil; | 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.WxMpService; | ||||
| import me.chanjar.weixin.mp.api.WxMpSubscribeMsgService; | import me.chanjar.weixin.mp.api.WxMpSubscribeMsgService; | ||||
| import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage; | 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.api.WxConsts; | ||||
| import me.chanjar.weixin.common.util.XmlUtils; | import me.chanjar.weixin.common.util.XmlUtils; | ||||
| import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | 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.crypto.WxMpCryptUtil; | ||||
| import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | ||||
| import me.chanjar.weixin.mp.util.xml.XStreamTransformer; | import me.chanjar.weixin.mp.util.xml.XStreamTransformer; | ||||
| @@ -527,10 +527,10 @@ public class WxMpXmlMessage implements Serializable { | |||||
| @XStreamAlias("DeviceID") | @XStreamAlias("DeviceID") | ||||
| @XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
| private String deviceId; | private String deviceId; | ||||
| /** | /** | ||||
| * 微信客户端生成的session id,用于request和response对应, | * 微信客户端生成的session id,用于request和response对应, | ||||
| * 因此响应中该字段第三方需要原封不变的带回 | |||||
| * 因此响应中该字段第三方需要原封不变的带回 | |||||
| */ | */ | ||||
| @XStreamAlias("SessionID") | @XStreamAlias("SessionID") | ||||
| @XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
| @@ -4,7 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
| import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | 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.builder.outxml.*; | ||||
| import me.chanjar.weixin.mp.util.crypto.WxMpCryptUtil; | import me.chanjar.weixin.mp.util.crypto.WxMpCryptUtil; | ||||
| import me.chanjar.weixin.mp.util.xml.XStreamTransformer; | import me.chanjar.weixin.mp.util.xml.XStreamTransformer; | ||||
| @@ -79,7 +79,7 @@ public abstract class WxMpXmlOutMessage implements Serializable { | |||||
| public static TransferCustomerServiceBuilder TRANSFER_CUSTOMER_SERVICE() { | public static TransferCustomerServiceBuilder TRANSFER_CUSTOMER_SERVICE() { | ||||
| return new TransferCustomerServiceBuilder(); | return new TransferCustomerServiceBuilder(); | ||||
| } | } | ||||
| /** | /** | ||||
| * 获得设备消息builder | * 获得设备消息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.bean.WxAccessToken; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | 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.File; | ||||
| import java.io.Serializable; | import java.io.Serializable; | ||||
| @@ -8,6 +8,7 @@ import java.util.concurrent.locks.ReentrantLock; | |||||
| import lombok.Data; | import lombok.Data; | ||||
| import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | 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.bean.WxMpHostConfig; | ||||
| import me.chanjar.weixin.mp.enums.TicketType; | import me.chanjar.weixin.mp.enums.TicketType; | ||||
| import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | ||||
| @@ -18,7 +19,7 @@ import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||||
| * @author chanjarster | * @author chanjarster | ||||
| */ | */ | ||||
| @Data | @Data | ||||
| public class WxMpInMemoryConfigStorage implements WxMpConfigStorage, Serializable { | |||||
| public class WxMpDefaultConfigImpl implements WxMpConfigStorage, Serializable { | |||||
| private static final long serialVersionUID = -6646519023303395185L; | private static final long serialVersionUID = -6646519023303395185L; | ||||
| protected volatile String appId; | 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 me.chanjar.weixin.mp.enums.TicketType; | ||||
| import redis.clients.jedis.Jedis; | import redis.clients.jedis.Jedis; | ||||
| @@ -15,17 +15,17 @@ import redis.clients.jedis.JedisPool; | |||||
| * @author nickwong | * @author nickwong | ||||
| */ | */ | ||||
| @SuppressWarnings("hiding") | @SuppressWarnings("hiding") | ||||
| public class WxMpInRedisConfigStorage extends WxMpInMemoryConfigStorage { | |||||
| public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl { | |||||
| private static final String ACCESS_TOKEN_KEY = "wx:access_token:"; | private static final String ACCESS_TOKEN_KEY = "wx:access_token:"; | ||||
| /** | /** | ||||
| * 使用连接池保证线程安全. | * 使用连接池保证线程安全. | ||||
| */ | */ | ||||
| protected final JedisPool jedisPool; | |||||
| private final JedisPool jedisPool; | |||||
| private String accessTokenKey; | private String accessTokenKey; | ||||
| public WxMpInRedisConfigStorage(JedisPool jedisPool) { | |||||
| public WxMpRedisConfigImpl(JedisPool jedisPool) { | |||||
| this.jedisPool = jedisPool; | this.jedisPool = jedisPool; | ||||
| } | } | ||||
| @@ -1,7 +1,7 @@ | |||||
| package me.chanjar.weixin.mp.enums; | package me.chanjar.weixin.mp.enums; | ||||
| import lombok.AllArgsConstructor; | 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.*; | import static me.chanjar.weixin.mp.bean.WxMpHostConfig.*; | ||||
| @@ -17,7 +17,7 @@ | |||||
| */ | */ | ||||
| package me.chanjar.weixin.mp.util.crypto; | 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; | import org.apache.commons.codec.binary.Base64; | ||||
| public class WxMpCryptUtil extends me.chanjar.weixin.common.util.crypto.WxCryptUtil { | 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 com.google.inject.Inject; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | 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.WxMpService; | ||||
| import me.chanjar.weixin.mp.api.test.ApiTestModule; | import me.chanjar.weixin.mp.api.test.ApiTestModule; | ||||
| import me.chanjar.weixin.mp.api.test.TestConfigStorage; | import me.chanjar.weixin.mp.api.test.TestConfigStorage; | ||||
| @@ -12,7 +12,7 @@ import com.google.inject.Binder; | |||||
| import com.google.inject.Module; | import com.google.inject.Module; | ||||
| import com.thoughtworks.xstream.XStream; | import com.thoughtworks.xstream.XStream; | ||||
| import me.chanjar.weixin.common.util.xml.XStreamInitializer; | 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; | import me.chanjar.weixin.mp.api.WxMpService; | ||||
| public class ApiTestModule implements Module { | public class ApiTestModule implements Module { | ||||
| @@ -1,13 +1,13 @@ | |||||
| package me.chanjar.weixin.mp.api.test; | package me.chanjar.weixin.mp.api.test; | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | 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 org.apache.commons.lang3.builder.ToStringBuilder; | ||||
| import java.util.concurrent.locks.Lock; | import java.util.concurrent.locks.Lock; | ||||
| @XStreamAlias("xml") | @XStreamAlias("xml") | ||||
| public class TestConfigStorage extends WxMpInMemoryConfigStorage { | |||||
| public class TestConfigStorage extends WxMpDefaultConfigImpl { | |||||
| private String openid; | private String openid; | ||||
| private String kfAccount; | private String kfAccount; | ||||
| @@ -6,13 +6,13 @@ import java.util.concurrent.locks.ReentrantLock; | |||||
| import com.thoughtworks.xstream.XStream; | import com.thoughtworks.xstream.XStream; | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import me.chanjar.weixin.common.util.xml.XStreamInitializer; | 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 | * @author Daniel Qian | ||||
| */ | */ | ||||
| @XStreamAlias("xml") | @XStreamAlias("xml") | ||||
| class WxMpDemoInMemoryConfigStorage extends WxMpInMemoryConfigStorage { | |||||
| class WxMpDemoInMemoryConfigStorage extends WxMpDefaultConfigImpl { | |||||
| private static final long serialVersionUID = -3706236839197109704L; | private static final long serialVersionUID = -3706236839197109704L; | ||||
| public static WxMpDemoInMemoryConfigStorage fromXml(InputStream is) { | public static WxMpDemoInMemoryConfigStorage fromXml(InputStream is) { | ||||
| @@ -1,7 +1,7 @@ | |||||
| package me.chanjar.weixin.mp.demo; | package me.chanjar.weixin.mp.demo; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | 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.WxMpMessageHandler; | ||||
| import me.chanjar.weixin.mp.api.WxMpMessageRouter; | import me.chanjar.weixin.mp.api.WxMpMessageRouter; | ||||
| import me.chanjar.weixin.mp.api.WxMpService; | import me.chanjar.weixin.mp.api.WxMpService; | ||||
| @@ -1,6 +1,6 @@ | |||||
| package me.chanjar.weixin.mp.demo; | 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.WxMpMessageRouter; | ||||
| import me.chanjar.weixin.mp.api.WxMpService; | import me.chanjar.weixin.mp.api.WxMpService; | ||||
| import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | 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 cn.binarywang.wx.miniapp.config.WxMaConfig; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | 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.WxOpenAuthorizerAccessToken; | ||||
| import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; | 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 cn.binarywang.wx.miniapp.config.WxMaConfig; | ||||
| import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | 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.bean.WxMpHostConfig; | ||||
| import me.chanjar.weixin.mp.enums.TicketType; | import me.chanjar.weixin.mp.enums.TicketType; | ||||
| import me.chanjar.weixin.open.api.WxOpenConfigStorage; | import me.chanjar.weixin.open.api.WxOpenConfigStorage; | ||||
| @@ -1,7 +1,7 @@ | |||||
| package me.chanjar.weixin.open.api.impl; | package me.chanjar.weixin.open.api.impl; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | 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.api.impl.WxMpServiceImpl; | ||||
| import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | ||||
| import me.chanjar.weixin.open.api.WxOpenComponentService; | 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.SimplePostRequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | ||||
| import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; | import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; | ||||
| import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||||
| import me.chanjar.weixin.open.api.WxOpenConfigStorage; | import me.chanjar.weixin.open.api.WxOpenConfigStorage; | ||||
| import org.apache.http.HttpHost; | import org.apache.http.HttpHost; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||