| @@ -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; | |||
| 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.cp.bean.WxCpXmlMessage; | |||
| @@ -24,6 +25,6 @@ public interface WxCpMessageHandler { | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, | |||
| Map<String, Object> context, | |||
| WxCpService wxCpService, | |||
| WxSessionManager sessionManager); | |||
| WxSessionManager sessionManager) throws WxErrorException; | |||
| } | |||
| @@ -1,5 +1,6 @@ | |||
| package me.chanjar.weixin.cp.api; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import me.chanjar.weixin.common.session.WxSessionManager; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | |||
| @@ -24,6 +25,6 @@ public interface WxCpMessageInterceptor { | |||
| public boolean intercept(WxCpXmlMessage wxMessage, | |||
| Map<String, Object> context, | |||
| WxCpService wxCpService, | |||
| WxSessionManager sessionManager); | |||
| WxSessionManager sessionManager) throws WxErrorException; | |||
| } | |||
| @@ -1,6 +1,9 @@ | |||
| package me.chanjar.weixin.cp.api; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| 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.WxMessageInMemoryDuplicateChecker; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | |||
| @@ -62,11 +65,14 @@ public class WxCpMessageRouter { | |||
| private WxSessionManager sessionManager; | |||
| private WxErrorExceptionHandler exceptionHandler; | |||
| public WxCpMessageRouter(WxCpService wxCpService) { | |||
| this.wxCpService = wxCpService; | |||
| this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE); | |||
| this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); | |||
| this.sessionManager = new StandardSessionManager(); | |||
| this.exceptionHandler = new LogExceptionHandler(); | |||
| } | |||
| /** | |||
| @@ -143,12 +149,12 @@ public class WxCpMessageRouter { | |||
| futures.add( | |||
| executorService.submit(new Runnable() { | |||
| public void run() { | |||
| rule.service(wxMessage, wxCpService, sessionManager); | |||
| rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler); | |||
| } | |||
| }) | |||
| ); | |||
| } else { | |||
| res = rule.service(wxMessage, wxCpService, sessionManager); | |||
| res = rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler); | |||
| // 在同步操作结束,session访问结束 | |||
| log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName()); | |||
| sessionEndAccess(wxMessage); | |||
| @@ -425,22 +431,35 @@ public class WxCpMessageRouter { | |||
| * @param wxMessage | |||
| * @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; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import me.chanjar.weixin.common.session.WxSessionManager; | |||
| import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | |||
| import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | |||
| @@ -23,6 +24,6 @@ public interface WxMpMessageHandler { | |||
| public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||
| Map<String, Object> context, | |||
| WxMpService wxMpService, | |||
| WxSessionManager sessionManager); | |||
| WxSessionManager sessionManager) throws WxErrorException; | |||
| } | |||
| @@ -1,5 +1,6 @@ | |||
| package me.chanjar.weixin.mp.api; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import me.chanjar.weixin.common.session.WxSessionManager; | |||
| import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | |||
| @@ -24,6 +25,6 @@ public interface WxMpMessageInterceptor { | |||
| public boolean intercept(WxMpXmlMessage wxMessage, | |||
| Map<String, Object> context, | |||
| WxMpService wxMpService, | |||
| WxSessionManager sessionManager); | |||
| WxSessionManager sessionManager) throws WxErrorException; | |||
| } | |||
| @@ -1,7 +1,12 @@ | |||
| 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.WxMessageInMemoryDuplicateChecker; | |||
| import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | |||
| @@ -61,11 +66,14 @@ public class WxMpMessageRouter { | |||
| private WxSessionManager sessionManager; | |||
| private WxErrorExceptionHandler exceptionHandler; | |||
| public WxMpMessageRouter(WxMpService wxMpService) { | |||
| this.wxMpService = wxMpService; | |||
| this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE); | |||
| this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); | |||
| this.sessionManager = new StandardSessionManager(); | |||
| this.exceptionHandler = new LogExceptionHandler(); | |||
| } | |||
| /** | |||
| @@ -142,12 +150,12 @@ public class WxMpMessageRouter { | |||
| futures.add( | |||
| executorService.submit(new Runnable() { | |||
| public void run() { | |||
| rule.service(wxMessage, wxMpService, sessionManager); | |||
| rule.service(wxMessage, wxMpService, sessionManager, exceptionHandler); | |||
| } | |||
| }) | |||
| ); | |||
| } else { | |||
| res = rule.service(wxMessage, wxMpService, sessionManager); | |||
| res = rule.service(wxMessage, wxMpService, sessionManager, exceptionHandler); | |||
| // 在同步操作结束,session访问结束 | |||
| log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName()); | |||
| sessionEndAccess(wxMessage); | |||
| @@ -409,22 +417,33 @@ public class WxMpMessageRouter { | |||
| * @param wxMessage | |||
| * @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 | |||
| public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, | |||
| WxSessionManager sessionManager) { | |||
| WxSessionManager sessionManager) throws WxErrorException { | |||
| if (isUserWantGuess(wxMessage)) { | |||
| 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()); | |||
| if (session.getAttribute("guessing") == null) { | |||
| WxMpCustomMessage m = WxMpCustomMessage | |||
| @@ -57,22 +57,14 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||
| .toUser(wxMessage.getFromUserName()) | |||
| .content("请猜一个100以内的数字") | |||
| .build(); | |||
| try { | |||
| wxMpService.customMessageSend(m); | |||
| } catch (WxErrorException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| wxMpService.customMessageSend(m); | |||
| } else { | |||
| WxMpCustomMessage m = WxMpCustomMessage | |||
| .TEXT() | |||
| .toUser(wxMessage.getFromUserName()) | |||
| .content("放弃了吗?那请重新猜一个100以内的数字") | |||
| .build(); | |||
| try { | |||
| wxMpService.customMessageSend(m); | |||
| } catch (WxErrorException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| wxMpService.customMessageSend(m); | |||
| } | |||
| 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()); | |||
| @@ -100,11 +92,7 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||
| .toUser(wxMessage.getFromUserName()) | |||
| .content("小了") | |||
| .build(); | |||
| try { | |||
| wxMpService.customMessageSend(m); | |||
| } catch (WxErrorException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| wxMpService.customMessageSend(m); | |||
| } else if (guessNumber > answer) { | |||
| WxMpCustomMessage m = WxMpCustomMessage | |||
| @@ -112,23 +100,15 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||
| .toUser(wxMessage.getFromUserName()) | |||
| .content("大了") | |||
| .build(); | |||
| try { | |||
| wxMpService.customMessageSend(m); | |||
| } catch (WxErrorException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| wxMpService.customMessageSend(m); | |||
| } else { | |||
| WxMpCustomMessage m = WxMpCustomMessage | |||
| .TEXT() | |||
| .toUser(wxMessage.getFromUserName()) | |||
| .content("Bingo!") | |||
| .build(); | |||
| try { | |||
| session.removeAttribute("guessing"); | |||
| wxMpService.customMessageSend(m); | |||
| } catch (WxErrorException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| session.removeAttribute("guessing"); | |||
| wxMpService.customMessageSend(m); | |||
| } | |||
| } | |||