@@ -39,11 +39,9 @@ public interface InternalSession { | |||||
void access(); | void access(); | ||||
/** | /** | ||||
* Set the <code>isNew</code> flag for this session. | |||||
* | |||||
* @param isNew The new value for the <code>isNew</code> flag | |||||
* End the access. | |||||
*/ | */ | ||||
void setNew(boolean isNew); | |||||
void endAccess(); | |||||
/** | /** | ||||
* Set the creation time for this session. This method is called by the | * Set the creation time for this session. This method is called by the | ||||
@@ -4,6 +4,7 @@ import me.chanjar.weixin.common.util.res.StringManager; | |||||
import java.util.*; | import java.util.*; | ||||
import java.util.concurrent.ConcurrentHashMap; | import java.util.concurrent.ConcurrentHashMap; | ||||
import java.util.concurrent.atomic.AtomicInteger; | |||||
public class SessionImpl implements WxSession, InternalSession { | public class SessionImpl implements WxSession, InternalSession { | ||||
@@ -90,11 +91,6 @@ public class SessionImpl implements WxSession, InternalSession { | |||||
*/ | */ | ||||
protected volatile boolean isValid = false; | protected volatile boolean isValid = false; | ||||
/** | |||||
* Flag indicating whether this session is new or not. | |||||
*/ | |||||
protected boolean isNew = false; | |||||
/** | /** | ||||
* We are currently processing a session expiration, so bypass | * We are currently processing a session expiration, so bypass | ||||
* certain IllegalStateException tests. NOTE: This value is not | * certain IllegalStateException tests. NOTE: This value is not | ||||
@@ -123,11 +119,6 @@ public class SessionImpl implements WxSession, InternalSession { | |||||
*/ | */ | ||||
protected volatile long thisAccessedTime = creationTime; | protected volatile long thisAccessedTime = creationTime; | ||||
/** | |||||
* The last accessed time for this Session. | |||||
*/ | |||||
protected volatile long lastAccessedTime = creationTime; | |||||
/** | /** | ||||
* The default maximum inactive interval for Sessions created by | * The default maximum inactive interval for Sessions created by | ||||
* this Manager. | * this Manager. | ||||
@@ -140,9 +131,15 @@ public class SessionImpl implements WxSession, InternalSession { | |||||
*/ | */ | ||||
protected transient InternalSessionFacade facade = null; | protected transient InternalSessionFacade facade = null; | ||||
/** | |||||
* The access count for this session. | |||||
*/ | |||||
protected transient AtomicInteger accessCount = null; | |||||
public SessionImpl(InternalSessionManager manager) { | public SessionImpl(InternalSessionManager manager) { | ||||
this.manager = manager; | this.manager = manager; | ||||
this.accessCount = new AtomicInteger(); | |||||
} | } | ||||
@@ -176,7 +173,28 @@ public class SessionImpl implements WxSession, InternalSession { | |||||
@Override | @Override | ||||
public boolean isValid() { | public boolean isValid() { | ||||
return isValid; | |||||
if (!this.isValid) { | |||||
return false; | |||||
} | |||||
if (this.expiring) { | |||||
return true; | |||||
} | |||||
if (accessCount.get() > 0) { | |||||
return true; | |||||
} | |||||
if (maxInactiveInterval > 0) { | |||||
long timeNow = System.currentTimeMillis(); | |||||
int timeIdle; | |||||
timeIdle = (int) ((timeNow - thisAccessedTime) / 1000L); | |||||
if (timeIdle >= maxInactiveInterval) { | |||||
expire(); | |||||
} | |||||
} | |||||
return this.isValid; | |||||
} | } | ||||
@Override | @Override | ||||
@@ -215,6 +233,8 @@ public class SessionImpl implements WxSession, InternalSession { | |||||
// Mark this session as "being expired" | // Mark this session as "being expired" | ||||
expiring = true; | expiring = true; | ||||
accessCount.set(0); | |||||
// Remove this session from our manager's active sessions | // Remove this session from our manager's active sessions | ||||
manager.remove(this, true); | manager.remove(this, true); | ||||
@@ -238,23 +258,23 @@ public class SessionImpl implements WxSession, InternalSession { | |||||
public void access() { | public void access() { | ||||
this.thisAccessedTime = System.currentTimeMillis(); | this.thisAccessedTime = System.currentTimeMillis(); | ||||
accessCount.incrementAndGet(); | |||||
} | } | ||||
@Override | @Override | ||||
public void setNew(boolean isNew) { | |||||
public void endAccess() { | |||||
this.isNew = isNew; | |||||
this.thisAccessedTime = System.currentTimeMillis(); | |||||
accessCount.decrementAndGet(); | |||||
} | } | ||||
@Override | @Override | ||||
public void setCreationTime(long time) { | public void setCreationTime(long time) { | ||||
this.creationTime = time; | this.creationTime = time; | ||||
this.lastAccessedTime = time; | |||||
this.thisAccessedTime = time; | this.thisAccessedTime = time; | ||||
} | } | ||||
@@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.concurrent.ConcurrentHashMap; | import java.util.concurrent.ConcurrentHashMap; | ||||
import java.util.concurrent.atomic.AtomicBoolean; | |||||
public class SessionManagerImpl implements WxSessionManager, InternalSessionManager { | public class SessionManagerImpl implements WxSessionManager, InternalSessionManager { | ||||
@@ -104,6 +105,11 @@ public class SessionManagerImpl implements WxSessionManager, InternalSessionMana | |||||
*/ | */ | ||||
protected int processExpiresFrequency = 6; | protected int processExpiresFrequency = 6; | ||||
/** | |||||
* 后台清理线程是否已经开启 | |||||
*/ | |||||
private final AtomicBoolean backgroundProcessStarted = new AtomicBoolean(false); | |||||
@Override | @Override | ||||
public void remove(InternalSession session) { | public void remove(InternalSession session) { | ||||
remove(session, false); | remove(session, false); | ||||
@@ -155,7 +161,6 @@ public class SessionManagerImpl implements WxSessionManager, InternalSessionMana | |||||
InternalSession session = createEmptySession(); | InternalSession session = createEmptySession(); | ||||
// Initialize the properties of the new session and return it | // Initialize the properties of the new session and return it | ||||
session.setNew(true); | |||||
session.setValid(true); | session.setValid(true); | ||||
session.setCreationTime(System.currentTimeMillis()); | session.setCreationTime(System.currentTimeMillis()); | ||||
session.setMaxInactiveInterval(this.maxInactiveInterval); | session.setMaxInactiveInterval(this.maxInactiveInterval); | ||||
@@ -191,6 +196,26 @@ public class SessionManagerImpl implements WxSessionManager, InternalSessionMana | |||||
@Override | @Override | ||||
public void add(InternalSession session) { | public void add(InternalSession session) { | ||||
// 当第一次有session创建的时候,开启session清理线程 | |||||
if (!backgroundProcessStarted.getAndSet(true)) { | |||||
Thread t = new Thread(new Runnable() { | |||||
@Override | |||||
public void run() { | |||||
while (true) { | |||||
try { | |||||
// 每秒清理一次 | |||||
Thread.sleep(1000l); | |||||
backgroundProcess(); | |||||
} catch (InterruptedException e) { | |||||
log.error("SessionManagerImpl.backgroundProcess error", e); | |||||
} | |||||
} | |||||
} | |||||
}); | |||||
t.setDaemon(true); | |||||
t.start(); | |||||
} | |||||
sessions.put(session.getIdInternal(), session); | sessions.put(session.getIdInternal(), session); | ||||
int size = getActiveSessions(); | int size = getActiveSessions(); | ||||
if( size > maxActive ) { | if( size > maxActive ) { | ||||
@@ -2,9 +2,19 @@ package me.chanjar.weixin.common.session; | |||||
public interface WxSessionManager { | public interface WxSessionManager { | ||||
/** | |||||
* 获取某个sessionId对应的session,如果sessionId没有对应的session,则新建一个并返回。 | |||||
* @param sessionId | |||||
* @return | |||||
*/ | |||||
public WxSession getSession(String sessionId); | public WxSession getSession(String sessionId); | ||||
/** | |||||
* 获取某个sessionId对应的session,如果sessionId没有对应的session,若create为true则新建一个,否则返回null。 | |||||
* @param sessionId | |||||
* @param create | |||||
* @return | |||||
*/ | |||||
public WxSession getSession(String sessionId, boolean create); | public WxSession getSession(String sessionId, boolean create); | ||||
@@ -2,6 +2,7 @@ package me.chanjar.weixin.common.util; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.concurrent.ConcurrentHashMap; | import java.util.concurrent.ConcurrentHashMap; | ||||
import java.util.concurrent.atomic.AtomicBoolean; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -21,8 +22,16 @@ public class WxMsgIdMemoryDuplicateChecker implements WxMsgIdDuplicateChecker { | |||||
*/ | */ | ||||
private final Long clearPeriod; | private final Long clearPeriod; | ||||
/** | |||||
* 消息id->消息时间戳的map | |||||
*/ | |||||
private final ConcurrentHashMap<Long, Long> msgId2Timestamp = new ConcurrentHashMap<Long, Long>(); | private final ConcurrentHashMap<Long, Long> msgId2Timestamp = new ConcurrentHashMap<Long, Long>(); | ||||
/** | |||||
* 后台清理线程是否已经开启 | |||||
*/ | |||||
private final AtomicBoolean backgroundProcessStarted = new AtomicBoolean(false); | |||||
/** | /** | ||||
* WxMsgIdInMemoryDuplicateChecker构造函数 | * WxMsgIdInMemoryDuplicateChecker构造函数 | ||||
* <pre> | * <pre> | ||||
@@ -33,7 +42,6 @@ public class WxMsgIdMemoryDuplicateChecker implements WxMsgIdDuplicateChecker { | |||||
public WxMsgIdMemoryDuplicateChecker() { | public WxMsgIdMemoryDuplicateChecker() { | ||||
this.timeToLive = 15 * 1000l; | this.timeToLive = 15 * 1000l; | ||||
this.clearPeriod = 5 * 1000l; | this.clearPeriod = 5 * 1000l; | ||||
this.start(); | |||||
} | } | ||||
/** | /** | ||||
@@ -44,10 +52,12 @@ public class WxMsgIdMemoryDuplicateChecker implements WxMsgIdDuplicateChecker { | |||||
public WxMsgIdMemoryDuplicateChecker(Long timeToLive, Long clearPeriod) { | public WxMsgIdMemoryDuplicateChecker(Long timeToLive, Long clearPeriod) { | ||||
this.timeToLive = timeToLive; | this.timeToLive = timeToLive; | ||||
this.clearPeriod = clearPeriod; | this.clearPeriod = clearPeriod; | ||||
this.start(); | |||||
} | } | ||||
private void start() { | |||||
protected void checkBackgroundProcessStarted() { | |||||
if (backgroundProcessStarted.getAndSet(true)) { | |||||
return; | |||||
} | |||||
Thread t = new Thread(new Runnable() { | Thread t = new Thread(new Runnable() { | ||||
@Override | @Override | ||||
public void run() { | public void run() { | ||||
@@ -72,6 +82,7 @@ public class WxMsgIdMemoryDuplicateChecker implements WxMsgIdDuplicateChecker { | |||||
@Override | @Override | ||||
public boolean isDuplicate(Long wxMsgId) { | public boolean isDuplicate(Long wxMsgId) { | ||||
checkBackgroundProcessStarted(); | |||||
Long timestamp = msgId2Timestamp.putIfAbsent(wxMsgId, System.currentTimeMillis()); | Long timestamp = msgId2Timestamp.putIfAbsent(wxMsgId, System.currentTimeMillis()); | ||||
if (timestamp == null) { | if (timestamp == null) { | ||||
// 第一次接收到这个消息 | // 第一次接收到这个消息 | ||||
@@ -3,6 +3,8 @@ package me.chanjar.weixin.cp.api; | |||||
import me.chanjar.weixin.common.bean.WxMenu; | import me.chanjar.weixin.common.bean.WxMenu; | ||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.session.WxSession; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | |||||
import me.chanjar.weixin.common.util.http.RequestExecutor; | import me.chanjar.weixin.common.util.http.RequestExecutor; | ||||
import me.chanjar.weixin.cp.bean.WxCpDepart; | import me.chanjar.weixin.cp.bean.WxCpDepart; | ||||
import me.chanjar.weixin.cp.bean.WxCpMessage; | import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
@@ -371,4 +373,28 @@ public interface WxCpService { | |||||
* @param maxRetryTimes | * @param maxRetryTimes | ||||
*/ | */ | ||||
void setMaxRetryTimes(int maxRetryTimes); | void setMaxRetryTimes(int maxRetryTimes); | ||||
/** | |||||
* 获取某个sessionId对应的session,如果sessionId没有对应的session,则新建一个并返回。 | |||||
* @param id id可以为任意字符串,建议使用FromUserName作为id | |||||
* @return | |||||
*/ | |||||
WxSession getSession(String id); | |||||
/** | |||||
* 获取某个sessionId对应的session,如果sessionId没有对应的session,若create为true则新建一个,否则返回null。 | |||||
* @param id id可以为任意字符串,建议使用FromUserName作为id | |||||
* @param create | |||||
* @return | |||||
*/ | |||||
WxSession getSession(String id, boolean create); | |||||
/** | |||||
* <pre> | |||||
* 设置WxSessionManager,只有当需要使用个性化的WxSessionManager的时候才需要调用此方法, | |||||
* WxCpService默认使用的是{@link me.chanjar.weixin.common.session.SessionManagerImpl} | |||||
* </pre> | |||||
* @param sessionManager | |||||
*/ | |||||
void setSessionManager(WxSessionManager sessionManager); | |||||
} | } |
@@ -12,6 +12,9 @@ import me.chanjar.weixin.common.bean.WxMenu; | |||||
import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.session.SessionManagerImpl; | |||||
import me.chanjar.weixin.common.session.WxSession; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | |||||
import me.chanjar.weixin.common.util.StringUtils; | import me.chanjar.weixin.common.util.StringUtils; | ||||
import me.chanjar.weixin.common.util.crypto.SHA1; | import me.chanjar.weixin.common.util.crypto.SHA1; | ||||
import me.chanjar.weixin.common.util.fs.FileUtils; | import me.chanjar.weixin.common.util.fs.FileUtils; | ||||
@@ -64,6 +67,8 @@ public class WxCpServiceImpl implements WxCpService { | |||||
private int maxRetryTimes = 5; | private int maxRetryTimes = 5; | ||||
protected WxSessionManager sessionManager = new SessionManagerImpl(); | |||||
public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) { | public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) { | ||||
try { | try { | ||||
return SHA1.gen(wxCpConfigStorage.getToken(), timestamp, nonce, data).equals(msgSignature); | return SHA1.gen(wxCpConfigStorage.getToken(), timestamp, nonce, data).equals(msgSignature); | ||||
@@ -473,4 +478,26 @@ public class WxCpServiceImpl implements WxCpService { | |||||
this.maxRetryTimes = maxRetryTimes; | this.maxRetryTimes = maxRetryTimes; | ||||
} | } | ||||
@Override | |||||
public WxSession getSession(String id) { | |||||
if (sessionManager == null) { | |||||
return null; | |||||
} | |||||
return sessionManager.getSession(id); | |||||
} | |||||
@Override | |||||
public WxSession getSession(String id, boolean create) { | |||||
if (sessionManager == null) { | |||||
return null; | |||||
} | |||||
return sessionManager.getSession(id, create); | |||||
} | |||||
@Override | |||||
public void setSessionManager(WxSessionManager sessionManager) { | |||||
this.sessionManager = sessionManager; | |||||
} | |||||
} | } |
@@ -1,16 +1,25 @@ | |||||
package me.chanjar.weixin.mp.api; | package me.chanjar.weixin.mp.api; | ||||
import me.chanjar.weixin.common.session.InternalSession; | |||||
import me.chanjar.weixin.common.session.SessionManagerImpl; | |||||
import me.chanjar.weixin.common.session.WxSession; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | |||||
import me.chanjar.weixin.common.util.WxMsgIdDuplicateChecker; | import me.chanjar.weixin.common.util.WxMsgIdDuplicateChecker; | ||||
import me.chanjar.weixin.common.util.WxMsgIdMemoryDuplicateChecker; | import me.chanjar.weixin.common.util.WxMsgIdMemoryDuplicateChecker; | ||||
import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | ||||
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | ||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import javax.swing.text.StyledEditorKit; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.concurrent.ExecutionException; | |||||
import java.util.concurrent.ExecutorService; | import java.util.concurrent.ExecutorService; | ||||
import java.util.concurrent.Executors; | import java.util.concurrent.Executors; | ||||
import java.util.concurrent.Future; | |||||
import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||
/** | /** | ||||
@@ -41,6 +50,8 @@ import java.util.regex.Pattern; | |||||
*/ | */ | ||||
public class WxMpMessageRouter { | public class WxMpMessageRouter { | ||||
protected final Logger log = LoggerFactory.getLogger(WxMpMessageRouter.class); | |||||
private static final int DEFAULT_THREAD_POOL_SIZE = 20; | private static final int DEFAULT_THREAD_POOL_SIZE = 20; | ||||
private final List<Rule> rules = new ArrayList<Rule>(); | private final List<Rule> rules = new ArrayList<Rule>(); | ||||
@@ -51,6 +62,8 @@ public class WxMpMessageRouter { | |||||
private WxMsgIdDuplicateChecker wxMsgIdDuplicateChecker; | private WxMsgIdDuplicateChecker wxMsgIdDuplicateChecker; | ||||
protected WxSessionManager sessionManager = new SessionManagerImpl(); | |||||
public WxMpMessageRouter(WxMpService wxMpService) { | public WxMpMessageRouter(WxMpService wxMpService) { | ||||
this.wxMpService = wxMpService; | this.wxMpService = wxMpService; | ||||
this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE); | this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE); | ||||
@@ -113,21 +126,54 @@ public class WxMpMessageRouter { | |||||
} | } | ||||
WxMpXmlOutMessage res = null; | WxMpXmlOutMessage res = null; | ||||
final List<Future> futures = new ArrayList<Future>(); | |||||
for (final Rule rule : matchRules) { | for (final Rule rule : matchRules) { | ||||
// 返回最后一个非异步的rule的执行结果 | // 返回最后一个非异步的rule的执行结果 | ||||
if(rule.async) { | if(rule.async) { | ||||
executorService.submit(new Runnable() { | |||||
public void run() { | |||||
rule.service(wxMessage); | |||||
} | |||||
}); | |||||
futures.add( | |||||
executorService.submit(new Runnable() { | |||||
public void run() { | |||||
rule.service(wxMessage); | |||||
} | |||||
}) | |||||
); | |||||
} else { | } else { | ||||
res = rule.service(wxMessage); | res = rule.service(wxMessage); | ||||
} | } | ||||
} | } | ||||
// 告诉session,它已经用不着了 | |||||
if (futures.size() > 0) { | |||||
executorService.submit(new Runnable() { | |||||
@Override | |||||
public void run() { | |||||
for (Future future : futures) { | |||||
try { | |||||
future.get(); | |||||
} catch (InterruptedException e) { | |||||
log.error("Error happened when wait task finish", e); | |||||
} catch (ExecutionException e) { | |||||
log.error("Error happened when wait task finish", e); | |||||
} | |||||
} | |||||
// 在这里session再也不会被使用了 | |||||
sessionEndAccess(wxMessage); | |||||
} | |||||
}); | |||||
} else { | |||||
// 在这里session再也不会被使用了 | |||||
sessionEndAccess(wxMessage); | |||||
} | |||||
return res; | return res; | ||||
} | } | ||||
protected void sessionEndAccess(WxMpXmlMessage wxMessage) { | |||||
WxSession session = sessionManager.getSession(wxMessage.getFromUserName(), false); | |||||
if (session != null) { | |||||
((InternalSession) session).endAccess(); | |||||
} | |||||
} | |||||
public static class Rule { | public static class Rule { | ||||
private final WxMpMessageRouter routerBuilder; | private final WxMpMessageRouter routerBuilder; | ||||
@@ -3,6 +3,8 @@ package me.chanjar.weixin.mp.api; | |||||
import me.chanjar.weixin.common.bean.WxMenu; | import me.chanjar.weixin.common.bean.WxMenu; | ||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.session.WxSession; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | |||||
import me.chanjar.weixin.common.util.http.RequestExecutor; | import me.chanjar.weixin.common.util.http.RequestExecutor; | ||||
import me.chanjar.weixin.mp.bean.*; | import me.chanjar.weixin.mp.bean.*; | ||||
import me.chanjar.weixin.mp.bean.result.*; | import me.chanjar.weixin.mp.bean.result.*; | ||||
@@ -456,10 +458,10 @@ public interface WxMpService { | |||||
*/ | */ | ||||
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException; | public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException; | ||||
/** | |||||
* 注入 {@link WxMpConfigStorage} 的实现 | |||||
* @param wxConfigProvider | |||||
*/ | |||||
/** | |||||
* 注入 {@link WxMpConfigStorage} 的实现 | |||||
* @param wxConfigProvider | |||||
*/ | |||||
public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider); | public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider); | ||||
/** | /** | ||||
@@ -479,4 +481,5 @@ public interface WxMpService { | |||||
* @param maxRetryTimes | * @param maxRetryTimes | ||||
*/ | */ | ||||
void setMaxRetryTimes(int maxRetryTimes); | void setMaxRetryTimes(int maxRetryTimes); | ||||
} | } |
@@ -10,6 +10,9 @@ import me.chanjar.weixin.common.bean.WxMenu; | |||||
import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.session.SessionManagerImpl; | |||||
import me.chanjar.weixin.common.session.WxSession; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | |||||
import me.chanjar.weixin.common.util.StringUtils; | import me.chanjar.weixin.common.util.StringUtils; | ||||
import me.chanjar.weixin.common.util.crypto.SHA1; | import me.chanjar.weixin.common.util.crypto.SHA1; | ||||
import me.chanjar.weixin.common.util.fs.FileUtils; | import me.chanjar.weixin.common.util.fs.FileUtils; | ||||
@@ -66,6 +69,8 @@ public class WxMpServiceImpl implements WxMpService { | |||||
private int maxRetryTimes = 5; | private int maxRetryTimes = 5; | ||||
protected WxSessionManager sessionManager = new SessionManagerImpl(); | |||||
public boolean checkSignature(String timestamp, String nonce, String signature) { | public boolean checkSignature(String timestamp, String nonce, String signature) { | ||||
try { | try { | ||||
return SHA1.gen(wxMpConfigStorage.getToken(), timestamp, nonce).equals(signature); | return SHA1.gen(wxMpConfigStorage.getToken(), timestamp, nonce).equals(signature); | ||||
@@ -545,7 +550,6 @@ public class WxMpServiceImpl implements WxMpService { | |||||
} | } | ||||
} | } | ||||
@Override | @Override | ||||
public void setRetrySleepMillis(int retrySleepMillis) { | public void setRetrySleepMillis(int retrySleepMillis) { | ||||
this.retrySleepMillis = retrySleepMillis; | this.retrySleepMillis = retrySleepMillis; | ||||