@@ -0,0 +1,19 @@ | |||||
package me.chanjar.weixin.common.util; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
public class LogExceptionHandler implements WxErrorExceptionHandler { | |||||
private Logger log = LoggerFactory.getLogger(WxErrorExceptionHandler.class); | |||||
@Override | |||||
public void handle(WxErrorException e) { | |||||
log.error("Error happens", e); | |||||
} | |||||
} |
@@ -0,0 +1,12 @@ | |||||
package me.chanjar.weixin.common.util; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
/** | |||||
* WxErrorException处理器 | |||||
*/ | |||||
public interface WxErrorExceptionHandler { | |||||
public void handle(WxErrorException e); | |||||
} |
@@ -1,5 +1,6 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.session.WxSession; | import me.chanjar.weixin.common.session.WxSession; | ||||
import me.chanjar.weixin.common.session.WxSessionManager; | import me.chanjar.weixin.common.session.WxSessionManager; | ||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
@@ -24,6 +25,6 @@ public interface WxCpMessageHandler { | |||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, | public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, | ||||
Map<String, Object> context, | Map<String, Object> context, | ||||
WxCpService wxCpService, | WxCpService wxCpService, | ||||
WxSessionManager sessionManager); | |||||
WxSessionManager sessionManager) throws WxErrorException; | |||||
} | } |
@@ -1,5 +1,6 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | import me.chanjar.weixin.common.session.WxSessionManager; | ||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
@@ -24,6 +25,6 @@ public interface WxCpMessageInterceptor { | |||||
public boolean intercept(WxCpXmlMessage wxMessage, | public boolean intercept(WxCpXmlMessage wxMessage, | ||||
Map<String, Object> context, | Map<String, Object> context, | ||||
WxCpService wxCpService, | WxCpService wxCpService, | ||||
WxSessionManager sessionManager); | |||||
WxSessionManager sessionManager) throws WxErrorException; | |||||
} | } |
@@ -1,6 +1,9 @@ | |||||
package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.session.*; | import me.chanjar.weixin.common.session.*; | ||||
import me.chanjar.weixin.common.util.LogExceptionHandler; | |||||
import me.chanjar.weixin.common.util.WxErrorExceptionHandler; | |||||
import me.chanjar.weixin.common.util.WxMessageDuplicateChecker; | import me.chanjar.weixin.common.util.WxMessageDuplicateChecker; | ||||
import me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker; | import me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker; | ||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
@@ -62,11 +65,14 @@ public class WxCpMessageRouter { | |||||
private WxSessionManager sessionManager; | private WxSessionManager sessionManager; | ||||
private WxErrorExceptionHandler exceptionHandler; | |||||
public WxCpMessageRouter(WxCpService wxCpService) { | public WxCpMessageRouter(WxCpService wxCpService) { | ||||
this.wxCpService = wxCpService; | this.wxCpService = wxCpService; | ||||
this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE); | this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE); | ||||
this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); | this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); | ||||
this.sessionManager = new StandardSessionManager(); | this.sessionManager = new StandardSessionManager(); | ||||
this.exceptionHandler = new LogExceptionHandler(); | |||||
} | } | ||||
/** | /** | ||||
@@ -143,12 +149,12 @@ public class WxCpMessageRouter { | |||||
futures.add( | futures.add( | ||||
executorService.submit(new Runnable() { | executorService.submit(new Runnable() { | ||||
public void run() { | public void run() { | ||||
rule.service(wxMessage, wxCpService, sessionManager); | |||||
rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler); | |||||
} | } | ||||
}) | }) | ||||
); | ); | ||||
} else { | } else { | ||||
res = rule.service(wxMessage, wxCpService, sessionManager); | |||||
res = rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler); | |||||
// 在同步操作结束,session访问结束 | // 在同步操作结束,session访问结束 | ||||
log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName()); | log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName()); | ||||
sessionEndAccess(wxMessage); | sessionEndAccess(wxMessage); | ||||
@@ -425,22 +431,35 @@ public class WxCpMessageRouter { | |||||
* @param wxMessage | * @param wxMessage | ||||
* @return true 代表继续执行别的router,false 代表停止执行别的router | * @return true 代表继续执行别的router,false 代表停止执行别的router | ||||
*/ | */ | ||||
protected WxCpXmlOutMessage service(WxCpXmlMessage wxMessage, WxCpService wxCpService, WxSessionManager sessionManager) { | |||||
Map<String, Object> context = new HashMap<String, Object>(); | |||||
// 如果拦截器不通过 | |||||
for (WxCpMessageInterceptor interceptor : this.interceptors) { | |||||
if (!interceptor.intercept(wxMessage, context, wxCpService, sessionManager)) { | |||||
return null; | |||||
protected WxCpXmlOutMessage service(WxCpXmlMessage wxMessage, | |||||
WxCpService wxCpService, | |||||
WxSessionManager sessionManager, | |||||
WxErrorExceptionHandler exceptionHandler) { | |||||
try { | |||||
Map<String, Object> context = new HashMap<String, Object>(); | |||||
// 如果拦截器不通过 | |||||
for (WxCpMessageInterceptor interceptor : this.interceptors) { | |||||
if (!interceptor.intercept(wxMessage, context, wxCpService, sessionManager)) { | |||||
return null; | |||||
} | |||||
} | } | ||||
} | |||||
// 交给handler处理 | |||||
WxCpXmlOutMessage res = null; | |||||
for (WxCpMessageHandler handler : this.handlers) { | |||||
// 返回最后handler的结果 | |||||
res = handler.handle(wxMessage, context, wxCpService, sessionManager); | |||||
// 交给handler处理 | |||||
WxCpXmlOutMessage res = null; | |||||
for (WxCpMessageHandler handler : this.handlers) { | |||||
// 返回最后handler的结果 | |||||
res = handler.handle(wxMessage, context, wxCpService, sessionManager); | |||||
} | |||||
return res; | |||||
} catch (WxErrorException e) { | |||||
exceptionHandler.handle(e); | |||||
} | } | ||||
return res; | |||||
return null; | |||||
} | } | ||||
} | } | ||||
@@ -1,5 +1,6 @@ | |||||
package me.chanjar.weixin.mp.api; | package me.chanjar.weixin.mp.api; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | import me.chanjar.weixin.common.session.WxSessionManager; | ||||
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; | ||||
@@ -23,6 +24,6 @@ public interface WxMpMessageHandler { | |||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | ||||
Map<String, Object> context, | Map<String, Object> context, | ||||
WxMpService wxMpService, | WxMpService wxMpService, | ||||
WxSessionManager sessionManager); | |||||
WxSessionManager sessionManager) throws WxErrorException; | |||||
} | } |
@@ -1,5 +1,6 @@ | |||||
package me.chanjar.weixin.mp.api; | package me.chanjar.weixin.mp.api; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | import me.chanjar.weixin.common.session.WxSessionManager; | ||||
import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | ||||
@@ -24,6 +25,6 @@ public interface WxMpMessageInterceptor { | |||||
public boolean intercept(WxMpXmlMessage wxMessage, | public boolean intercept(WxMpXmlMessage wxMessage, | ||||
Map<String, Object> context, | Map<String, Object> context, | ||||
WxMpService wxMpService, | WxMpService wxMpService, | ||||
WxSessionManager sessionManager); | |||||
WxSessionManager sessionManager) throws WxErrorException; | |||||
} | } |
@@ -1,7 +1,12 @@ | |||||
package me.chanjar.weixin.mp.api; | package me.chanjar.weixin.mp.api; | ||||
import me.chanjar.weixin.common.api.WxConsts; | |||||
import me.chanjar.weixin.common.session.*; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.common.session.InternalSession; | |||||
import me.chanjar.weixin.common.session.InternalSessionManager; | |||||
import me.chanjar.weixin.common.session.StandardSessionManager; | |||||
import me.chanjar.weixin.common.session.WxSessionManager; | |||||
import me.chanjar.weixin.common.util.LogExceptionHandler; | |||||
import me.chanjar.weixin.common.util.WxErrorExceptionHandler; | |||||
import me.chanjar.weixin.common.util.WxMessageDuplicateChecker; | import me.chanjar.weixin.common.util.WxMessageDuplicateChecker; | ||||
import me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker; | import me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker; | ||||
import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | ||||
@@ -61,11 +66,14 @@ public class WxMpMessageRouter { | |||||
private WxSessionManager sessionManager; | private WxSessionManager sessionManager; | ||||
private WxErrorExceptionHandler exceptionHandler; | |||||
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); | ||||
this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); | this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); | ||||
this.sessionManager = new StandardSessionManager(); | this.sessionManager = new StandardSessionManager(); | ||||
this.exceptionHandler = new LogExceptionHandler(); | |||||
} | } | ||||
/** | /** | ||||
@@ -142,12 +150,12 @@ public class WxMpMessageRouter { | |||||
futures.add( | futures.add( | ||||
executorService.submit(new Runnable() { | executorService.submit(new Runnable() { | ||||
public void run() { | public void run() { | ||||
rule.service(wxMessage, wxMpService, sessionManager); | |||||
rule.service(wxMessage, wxMpService, sessionManager, exceptionHandler); | |||||
} | } | ||||
}) | }) | ||||
); | ); | ||||
} else { | } else { | ||||
res = rule.service(wxMessage, wxMpService, sessionManager); | |||||
res = rule.service(wxMessage, wxMpService, sessionManager, exceptionHandler); | |||||
// 在同步操作结束,session访问结束 | // 在同步操作结束,session访问结束 | ||||
log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName()); | log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName()); | ||||
sessionEndAccess(wxMessage); | sessionEndAccess(wxMessage); | ||||
@@ -409,22 +417,33 @@ public class WxMpMessageRouter { | |||||
* @param wxMessage | * @param wxMessage | ||||
* @return true 代表继续执行别的router,false 代表停止执行别的router | * @return true 代表继续执行别的router,false 代表停止执行别的router | ||||
*/ | */ | ||||
protected WxMpXmlOutMessage service(WxMpXmlMessage wxMessage, WxMpService wxMpService, WxSessionManager sessionManager) { | |||||
Map<String, Object> context = new HashMap<String, Object>(); | |||||
// 如果拦截器不通过 | |||||
for (WxMpMessageInterceptor interceptor : this.interceptors) { | |||||
if (!interceptor.intercept(wxMessage, context, wxMpService, sessionManager)) { | |||||
return null; | |||||
protected WxMpXmlOutMessage service(WxMpXmlMessage wxMessage, | |||||
WxMpService wxMpService, | |||||
WxSessionManager sessionManager, | |||||
WxErrorExceptionHandler exceptionHandler) { | |||||
try { | |||||
Map<String, Object> context = new HashMap<String, Object>(); | |||||
// 如果拦截器不通过 | |||||
for (WxMpMessageInterceptor interceptor : this.interceptors) { | |||||
if (!interceptor.intercept(wxMessage, context, wxMpService, sessionManager)) { | |||||
return null; | |||||
} | |||||
} | } | ||||
// 交给handler处理 | |||||
WxMpXmlOutMessage res = null; | |||||
for (WxMpMessageHandler handler : this.handlers) { | |||||
// 返回最后handler的结果 | |||||
res = handler.handle(wxMessage, context, wxMpService, sessionManager); | |||||
} | |||||
return res; | |||||
} catch (WxErrorException e) { | |||||
exceptionHandler.handle(e); | |||||
} | } | ||||
// 交给handler处理 | |||||
WxMpXmlOutMessage res = null; | |||||
for (WxMpMessageHandler handler : this.handlers) { | |||||
// 返回最后handler的结果 | |||||
res = handler.handle(wxMessage, context, wxMpService, sessionManager); | |||||
} | |||||
return res; | |||||
return null; | |||||
} | } | ||||
} | } | ||||
@@ -35,7 +35,7 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||||
@Override | @Override | ||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, | ||||
WxSessionManager sessionManager) { | |||||
WxSessionManager sessionManager) throws WxErrorException { | |||||
if (isUserWantGuess(wxMessage)) { | if (isUserWantGuess(wxMessage)) { | ||||
letsGo(wxMessage, wxMpService, sessionManager); | letsGo(wxMessage, wxMpService, sessionManager); | ||||
@@ -49,7 +49,7 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||||
} | } | ||||
protected void letsGo(WxMpXmlMessage wxMessage, WxMpService wxMpService, WxSessionManager sessionManager) { | |||||
protected void letsGo(WxMpXmlMessage wxMessage, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { | |||||
WxSession session = sessionManager.getSession(wxMessage.getFromUserName()); | WxSession session = sessionManager.getSession(wxMessage.getFromUserName()); | ||||
if (session.getAttribute("guessing") == null) { | if (session.getAttribute("guessing") == null) { | ||||
WxMpCustomMessage m = WxMpCustomMessage | WxMpCustomMessage m = WxMpCustomMessage | ||||
@@ -57,22 +57,14 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||||
.toUser(wxMessage.getFromUserName()) | .toUser(wxMessage.getFromUserName()) | ||||
.content("请猜一个100以内的数字") | .content("请猜一个100以内的数字") | ||||
.build(); | .build(); | ||||
try { | |||||
wxMpService.customMessageSend(m); | |||||
} catch (WxErrorException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
wxMpService.customMessageSend(m); | |||||
} else { | } else { | ||||
WxMpCustomMessage m = WxMpCustomMessage | WxMpCustomMessage m = WxMpCustomMessage | ||||
.TEXT() | .TEXT() | ||||
.toUser(wxMessage.getFromUserName()) | .toUser(wxMessage.getFromUserName()) | ||||
.content("放弃了吗?那请重新猜一个100以内的数字") | .content("放弃了吗?那请重新猜一个100以内的数字") | ||||
.build(); | .build(); | ||||
try { | |||||
wxMpService.customMessageSend(m); | |||||
} catch (WxErrorException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
wxMpService.customMessageSend(m); | |||||
} | } | ||||
session.setAttribute("guessing", Boolean.TRUE); | session.setAttribute("guessing", Boolean.TRUE); | ||||
@@ -80,7 +72,7 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||||
} | } | ||||
protected void giveHint(WxMpXmlMessage wxMessage, WxMpService wxMpService, WxSessionManager sessionManager) { | |||||
protected void giveHint(WxMpXmlMessage wxMessage, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { | |||||
WxSession session = sessionManager.getSession(wxMessage.getFromUserName()); | WxSession session = sessionManager.getSession(wxMessage.getFromUserName()); | ||||
@@ -100,11 +92,7 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||||
.toUser(wxMessage.getFromUserName()) | .toUser(wxMessage.getFromUserName()) | ||||
.content("小了") | .content("小了") | ||||
.build(); | .build(); | ||||
try { | |||||
wxMpService.customMessageSend(m); | |||||
} catch (WxErrorException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
wxMpService.customMessageSend(m); | |||||
} else if (guessNumber > answer) { | } else if (guessNumber > answer) { | ||||
WxMpCustomMessage m = WxMpCustomMessage | WxMpCustomMessage m = WxMpCustomMessage | ||||
@@ -112,23 +100,15 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||||
.toUser(wxMessage.getFromUserName()) | .toUser(wxMessage.getFromUserName()) | ||||
.content("大了") | .content("大了") | ||||
.build(); | .build(); | ||||
try { | |||||
wxMpService.customMessageSend(m); | |||||
} catch (WxErrorException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
wxMpService.customMessageSend(m); | |||||
} else { | } else { | ||||
WxMpCustomMessage m = WxMpCustomMessage | WxMpCustomMessage m = WxMpCustomMessage | ||||
.TEXT() | .TEXT() | ||||
.toUser(wxMessage.getFromUserName()) | .toUser(wxMessage.getFromUserName()) | ||||
.content("Bingo!") | .content("Bingo!") | ||||
.build(); | .build(); | ||||
try { | |||||
session.removeAttribute("guessing"); | |||||
wxMpService.customMessageSend(m); | |||||
} catch (WxErrorException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
session.removeAttribute("guessing"); | |||||
wxMpService.customMessageSend(m); | |||||
} | } | ||||
} | } | ||||