mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-10-31 02:28:25 +08:00 
			
		
		
		
	issue #87 WxMessageRouter、Rule提供setter方法,便于使用spring等依赖注入框架
This commit is contained in:
		| @ -1,7 +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.InternalSession; | ||||||
| import me.chanjar.weixin.common.session.*; | 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.LogExceptionHandler; | ||||||
| import me.chanjar.weixin.common.util.WxErrorExceptionHandler; | import me.chanjar.weixin.common.util.WxErrorExceptionHandler; | ||||||
| import me.chanjar.weixin.common.util.WxMessageDuplicateChecker; | import me.chanjar.weixin.common.util.WxMessageDuplicateChecker; | ||||||
| @ -12,14 +14,11 @@ import org.slf4j.Logger; | |||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; |  | ||||||
| import java.util.concurrent.ExecutionException; | 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.concurrent.Future; | ||||||
| import java.util.regex.Pattern; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * <pre> |  * <pre> | ||||||
| @ -27,8 +26,8 @@ import java.util.regex.Pattern; | |||||||
|  * |  * | ||||||
|  * 说明: |  * 说明: | ||||||
|  * 1. 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理 |  * 1. 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理 | ||||||
|  * 2. 默认情况下消息只会被处理一次,除非使用 {@link Rule#next()} |  * 2. 默认情况下消息只会被处理一次,除非使用 {@link WxCpMessageRouterRule#next()} | ||||||
|  * 3. 规则的结束必须用{@link Rule#end()}或者{@link Rule#next()},否则不会生效 |  * 3. 规则的结束必须用{@link WxCpMessageRouterRule#end()}或者{@link WxCpMessageRouterRule#next()},否则不会生效 | ||||||
|  * |  * | ||||||
|  * 使用方法: |  * 使用方法: | ||||||
|  * WxCpMessageRouter router = new WxCpMessageRouter(); |  * WxCpMessageRouter router = new WxCpMessageRouter(); | ||||||
| @ -55,7 +54,7 @@ public class WxCpMessageRouter { | |||||||
|  |  | ||||||
|   private static final int DEFAULT_THREAD_POOL_SIZE = 100; |   private static final int DEFAULT_THREAD_POOL_SIZE = 100; | ||||||
|  |  | ||||||
|   private final List<Rule> rules = new ArrayList<Rule>(); |   private final List<WxCpMessageRouterRule> rules = new ArrayList<WxCpMessageRouterRule>(); | ||||||
|  |  | ||||||
|   private final WxCpService wxCpService; |   private final WxCpService wxCpService; | ||||||
|  |  | ||||||
| @ -100,7 +99,7 @@ public class WxCpMessageRouter { | |||||||
|   /** |   /** | ||||||
|    * <pre> |    * <pre> | ||||||
|    * 设置自定义的{@link me.chanjar.weixin.common.session.WxSessionManager} |    * 设置自定义的{@link me.chanjar.weixin.common.session.WxSessionManager} | ||||||
|    * 如果不调用该方法,默认使用 {@linke SessionManagerImpl} |    * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.session.StandardSessionManager} | ||||||
|    * </pre> |    * </pre> | ||||||
|    * @param sessionManager |    * @param sessionManager | ||||||
|    */ |    */ | ||||||
| @ -108,12 +107,27 @@ public class WxCpMessageRouter { | |||||||
|     this.sessionManager = sessionManager; |     this.sessionManager = sessionManager; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * <pre> | ||||||
|  |    * 设置自定义的{@link me.chanjar.weixin.common.util.WxErrorExceptionHandler} | ||||||
|  |    * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.LogExceptionHandler} | ||||||
|  |    * </pre> | ||||||
|  |    * @param exceptionHandler | ||||||
|  |    */ | ||||||
|  |   public void setExceptionHandler(WxErrorExceptionHandler exceptionHandler) { | ||||||
|  |     this.exceptionHandler = exceptionHandler; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   List<WxCpMessageRouterRule> getRules() { | ||||||
|  |     return this.rules; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 开始一个新的Route规则 |    * 开始一个新的Route规则 | ||||||
|    * @return |    * @return | ||||||
|    */ |    */ | ||||||
|   public Rule rule() { |   public WxCpMessageRouterRule rule() { | ||||||
|     return new Rule(this); |     return new WxCpMessageRouterRule(this); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @ -126,12 +140,12 @@ public class WxCpMessageRouter { | |||||||
|       return null; |       return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     final List<Rule> matchRules = new ArrayList<Rule>(); |     final List<WxCpMessageRouterRule> matchRules = new ArrayList<WxCpMessageRouterRule>(); | ||||||
|     // 收集匹配的规则 |     // 收集匹配的规则 | ||||||
|     for (final Rule rule : rules) { |     for (final WxCpMessageRouterRule rule : rules) { | ||||||
|       if (rule.test(wxMessage)) { |       if (rule.test(wxMessage)) { | ||||||
|         matchRules.add(rule); |         matchRules.add(rule); | ||||||
|         if(!rule.reEnter) { |         if(!rule.isReEnter()) { | ||||||
|           break; |           break; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @ -143,9 +157,9 @@ public class WxCpMessageRouter { | |||||||
|  |  | ||||||
|     WxCpXmlOutMessage res = null; |     WxCpXmlOutMessage res = null; | ||||||
|     final List<Future> futures = new ArrayList<Future>(); |     final List<Future> futures = new ArrayList<Future>(); | ||||||
|     for (final Rule rule : matchRules) { |     for (final WxCpMessageRouterRule rule : matchRules) { | ||||||
|       // 返回最后一个非异步的rule的执行结果 |       // 返回最后一个非异步的rule的执行结果 | ||||||
|       if(rule.async) { |       if(rule.isAsync()) { | ||||||
|         futures.add( |         futures.add( | ||||||
|             executorService.submit(new Runnable() { |             executorService.submit(new Runnable() { | ||||||
|               public void run() { |               public void run() { | ||||||
| @ -216,252 +230,5 @@ public class WxCpMessageRouter { | |||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public static class Rule { |  | ||||||
|  |  | ||||||
|     private final WxCpMessageRouter routerBuilder; |  | ||||||
|  |  | ||||||
|     private boolean async = true; |  | ||||||
|  |  | ||||||
|     private String fromUser; |  | ||||||
|  |  | ||||||
|     private String msgType; |  | ||||||
|  |  | ||||||
|     private String event; |  | ||||||
|  |  | ||||||
|     private String eventKey; |  | ||||||
|  |  | ||||||
|     private String content; |  | ||||||
|  |  | ||||||
|     private String rContent; |  | ||||||
|  |  | ||||||
|     private WxCpMessageMatcher matcher; |  | ||||||
|  |  | ||||||
|     private boolean reEnter = false; |  | ||||||
|  |  | ||||||
|     private Integer agentId; |  | ||||||
|  |  | ||||||
|     private List<WxCpMessageHandler> handlers = new ArrayList<WxCpMessageHandler>(); |  | ||||||
|  |  | ||||||
|     private List<WxCpMessageInterceptor> interceptors = new ArrayList<WxCpMessageInterceptor>(); |  | ||||||
|  |  | ||||||
|     protected Rule(WxCpMessageRouter routerBuilder) { |  | ||||||
|       this.routerBuilder = routerBuilder; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 设置是否异步执行,默认是true |  | ||||||
|      * @param async |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule async(boolean async) { |  | ||||||
|       this.async = async; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 如果agentId匹配 |  | ||||||
|      * @param agentId |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule agentId(Integer agentId) { |  | ||||||
|       this.agentId = agentId; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 如果msgType等于某值 |  | ||||||
|      * @param msgType |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule msgType(String msgType) { |  | ||||||
|       this.msgType = msgType; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 如果event等于某值 |  | ||||||
|      * @param event |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule event(String event) { |  | ||||||
|       this.event = event; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 如果eventKey等于某值 |  | ||||||
|      * @param eventKey |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule eventKey(String eventKey) { |  | ||||||
|       this.eventKey = eventKey; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 如果content等于某值 |  | ||||||
|      * @param content |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule content(String content) { |  | ||||||
|       this.content = content; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 如果content匹配该正则表达式 |  | ||||||
|      * @param regex |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule rContent(String regex) { |  | ||||||
|       this.rContent = regex; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 如果fromUser等于某值 |  | ||||||
|      * @param fromUser |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule fromUser(String fromUser) { |  | ||||||
|       this.fromUser = fromUser; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 如果消息匹配某个matcher,用在用户需要自定义更复杂的匹配规则的时候 |  | ||||||
|      * @param matcher |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule matcher(WxCpMessageMatcher matcher) { |  | ||||||
|       this.matcher = matcher; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 设置微信消息拦截器 |  | ||||||
|      * @param interceptor |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule interceptor(WxCpMessageInterceptor interceptor) { |  | ||||||
|       return interceptor(interceptor, (WxCpMessageInterceptor[]) null); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 设置微信消息拦截器 |  | ||||||
|      * @param interceptor |  | ||||||
|      * @param otherInterceptors |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule interceptor(WxCpMessageInterceptor interceptor, WxCpMessageInterceptor... otherInterceptors) { |  | ||||||
|       this.interceptors.add(interceptor); |  | ||||||
|       if (otherInterceptors != null && otherInterceptors.length > 0) { |  | ||||||
|         for (WxCpMessageInterceptor i : otherInterceptors) { |  | ||||||
|           this.interceptors.add(i); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 设置微信消息处理器 |  | ||||||
|      * @param handler |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule handler(WxCpMessageHandler handler) { |  | ||||||
|       return handler(handler, (WxCpMessageHandler[]) null); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 设置微信消息处理器 |  | ||||||
|      * @param handler |  | ||||||
|      * @param otherHandlers |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule handler(WxCpMessageHandler handler, WxCpMessageHandler... otherHandlers) { |  | ||||||
|       this.handlers.add(handler); |  | ||||||
|       if (otherHandlers != null && otherHandlers.length > 0) { |  | ||||||
|         for (WxCpMessageHandler i : otherHandlers) { |  | ||||||
|           this.handlers.add(i); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 规则结束,代表如果一个消息匹配该规则,那么它将不再会进入其他规则 |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public WxCpMessageRouter end() { |  | ||||||
|       this.routerBuilder.rules.add(this); |  | ||||||
|       return this.routerBuilder; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 规则结束,但是消息还会进入其他规则 |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public WxCpMessageRouter next() { |  | ||||||
|       this.reEnter = true; |  | ||||||
|       return end(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     protected boolean test(WxCpXmlMessage wxMessage) { |  | ||||||
|       return |  | ||||||
|           (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName())) |  | ||||||
|           && |  | ||||||
|           (this.agentId == null || this.agentId.equals(wxMessage.getAgentId())) |  | ||||||
|           && |  | ||||||
|           (this.msgType == null || this.msgType.equals(wxMessage.getMsgType())) |  | ||||||
|           && |  | ||||||
|           (this.event == null || this.event.equals(wxMessage.getEvent())) |  | ||||||
|           && |  | ||||||
|           (this.eventKey == null || this.eventKey.equals(wxMessage.getEventKey())) |  | ||||||
|           && |  | ||||||
|           (this.content == null || this.content.equals(wxMessage.getContent() == null ? null : wxMessage.getContent().trim())) |  | ||||||
|           && |  | ||||||
|           (this.rContent == null || Pattern.matches(this.rContent, wxMessage.getContent() == null ? "" : wxMessage.getContent().trim())) |  | ||||||
|           && |  | ||||||
|           (this.matcher == null || this.matcher.match(wxMessage)) |  | ||||||
|       ; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 处理微信推送过来的消息 |  | ||||||
|      * @param wxMessage |  | ||||||
|      * @return true 代表继续执行别的router,false 代表停止执行别的router |  | ||||||
|      */ |  | ||||||
|     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); |  | ||||||
|         } |  | ||||||
|         return res; |  | ||||||
|  |  | ||||||
|       } catch (WxErrorException e) { |  | ||||||
|         exceptionHandler.handle(e); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       return null; |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,335 @@ | |||||||
|  | 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.util.WxErrorExceptionHandler; | ||||||
|  | import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||||
|  | import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.regex.Pattern; | ||||||
|  |  | ||||||
|  | public class WxCpMessageRouterRule { | ||||||
|  |  | ||||||
|  |   private final WxCpMessageRouter routerBuilder; | ||||||
|  |  | ||||||
|  |   private boolean async = true; | ||||||
|  |  | ||||||
|  |   private String fromUser; | ||||||
|  |  | ||||||
|  |   private String msgType; | ||||||
|  |  | ||||||
|  |   private String event; | ||||||
|  |  | ||||||
|  |   private String eventKey; | ||||||
|  |  | ||||||
|  |   private String content; | ||||||
|  |  | ||||||
|  |   private String rContent; | ||||||
|  |  | ||||||
|  |   private WxCpMessageMatcher matcher; | ||||||
|  |  | ||||||
|  |   private boolean reEnter = false; | ||||||
|  |  | ||||||
|  |   private Integer agentId; | ||||||
|  |  | ||||||
|  |   private List<WxCpMessageHandler> handlers = new ArrayList<WxCpMessageHandler>(); | ||||||
|  |  | ||||||
|  |   private List<WxCpMessageInterceptor> interceptors = new ArrayList<WxCpMessageInterceptor>(); | ||||||
|  |  | ||||||
|  |   protected WxCpMessageRouterRule(WxCpMessageRouter routerBuilder) { | ||||||
|  |     this.routerBuilder = routerBuilder; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 设置是否异步执行,默认是true | ||||||
|  |    * | ||||||
|  |    * @param async | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule async(boolean async) { | ||||||
|  |     this.async = async; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果agentId匹配 | ||||||
|  |    * | ||||||
|  |    * @param agentId | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule agentId(Integer agentId) { | ||||||
|  |     this.agentId = agentId; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果msgType等于某值 | ||||||
|  |    * | ||||||
|  |    * @param msgType | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule msgType(String msgType) { | ||||||
|  |     this.msgType = msgType; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果event等于某值 | ||||||
|  |    * | ||||||
|  |    * @param event | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule event(String event) { | ||||||
|  |     this.event = event; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果eventKey等于某值 | ||||||
|  |    * | ||||||
|  |    * @param eventKey | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule eventKey(String eventKey) { | ||||||
|  |     this.eventKey = eventKey; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果content等于某值 | ||||||
|  |    * | ||||||
|  |    * @param content | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule content(String content) { | ||||||
|  |     this.content = content; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果content匹配该正则表达式 | ||||||
|  |    * | ||||||
|  |    * @param regex | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule rContent(String regex) { | ||||||
|  |     this.rContent = regex; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果fromUser等于某值 | ||||||
|  |    * | ||||||
|  |    * @param fromUser | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule fromUser(String fromUser) { | ||||||
|  |     this.fromUser = fromUser; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果消息匹配某个matcher,用在用户需要自定义更复杂的匹配规则的时候 | ||||||
|  |    * | ||||||
|  |    * @param matcher | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule matcher(WxCpMessageMatcher matcher) { | ||||||
|  |     this.matcher = matcher; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 设置微信消息拦截器 | ||||||
|  |    * | ||||||
|  |    * @param interceptor | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule interceptor(WxCpMessageInterceptor interceptor) { | ||||||
|  |     return interceptor(interceptor, (WxCpMessageInterceptor[]) null); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 设置微信消息拦截器 | ||||||
|  |    * | ||||||
|  |    * @param interceptor | ||||||
|  |    * @param otherInterceptors | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule interceptor(WxCpMessageInterceptor interceptor, WxCpMessageInterceptor... otherInterceptors) { | ||||||
|  |     this.interceptors.add(interceptor); | ||||||
|  |     if (otherInterceptors != null && otherInterceptors.length > 0) { | ||||||
|  |       for (WxCpMessageInterceptor i : otherInterceptors) { | ||||||
|  |         this.interceptors.add(i); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 设置微信消息处理器 | ||||||
|  |    * | ||||||
|  |    * @param handler | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule handler(WxCpMessageHandler handler) { | ||||||
|  |     return handler(handler, (WxCpMessageHandler[]) null); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 设置微信消息处理器 | ||||||
|  |    * | ||||||
|  |    * @param handler | ||||||
|  |    * @param otherHandlers | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouterRule handler(WxCpMessageHandler handler, WxCpMessageHandler... otherHandlers) { | ||||||
|  |     this.handlers.add(handler); | ||||||
|  |     if (otherHandlers != null && otherHandlers.length > 0) { | ||||||
|  |       for (WxCpMessageHandler i : otherHandlers) { | ||||||
|  |         this.handlers.add(i); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 规则结束,代表如果一个消息匹配该规则,那么它将不再会进入其他规则 | ||||||
|  |    * | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouter end() { | ||||||
|  |     this.routerBuilder.getRules().add(this); | ||||||
|  |     return this.routerBuilder; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 规则结束,但是消息还会进入其他规则 | ||||||
|  |    * | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxCpMessageRouter next() { | ||||||
|  |     this.reEnter = true; | ||||||
|  |     return end(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   protected boolean test(WxCpXmlMessage wxMessage) { | ||||||
|  |     return | ||||||
|  |         (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName())) | ||||||
|  |             && | ||||||
|  |             (this.agentId == null || this.agentId.equals(wxMessage.getAgentId())) | ||||||
|  |             && | ||||||
|  |             (this.msgType == null || this.msgType.equals(wxMessage.getMsgType())) | ||||||
|  |             && | ||||||
|  |             (this.event == null || this.event.equals(wxMessage.getEvent())) | ||||||
|  |             && | ||||||
|  |             (this.eventKey == null || this.eventKey.equals(wxMessage.getEventKey())) | ||||||
|  |             && | ||||||
|  |             (this.content == null || this.content | ||||||
|  |                 .equals(wxMessage.getContent() == null ? null : wxMessage.getContent().trim())) | ||||||
|  |             && | ||||||
|  |             (this.rContent == null || Pattern | ||||||
|  |                 .matches(this.rContent, wxMessage.getContent() == null ? "" : wxMessage.getContent().trim())) | ||||||
|  |             && | ||||||
|  |             (this.matcher == null || this.matcher.match(wxMessage)) | ||||||
|  |         ; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 处理微信推送过来的消息 | ||||||
|  |    * | ||||||
|  |    * @param wxMessage | ||||||
|  |    * @return true 代表继续执行别的router,false 代表停止执行别的router | ||||||
|  |    */ | ||||||
|  |   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); | ||||||
|  |       } | ||||||
|  |       return res; | ||||||
|  |  | ||||||
|  |     } catch (WxErrorException e) { | ||||||
|  |       exceptionHandler.handle(e); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return null; | ||||||
|  |  | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setFromUser(String fromUser) { | ||||||
|  |     this.fromUser = fromUser; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setMsgType(String msgType) { | ||||||
|  |     this.msgType = msgType; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setEvent(String event) { | ||||||
|  |     this.event = event; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setEventKey(String eventKey) { | ||||||
|  |     this.eventKey = eventKey; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setContent(String content) { | ||||||
|  |     this.content = content; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setrContent(String rContent) { | ||||||
|  |     this.rContent = rContent; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setMatcher(WxCpMessageMatcher matcher) { | ||||||
|  |     this.matcher = matcher; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setAgentId(Integer agentId) { | ||||||
|  |     this.agentId = agentId; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setHandlers(List<WxCpMessageHandler> handlers) { | ||||||
|  |     this.handlers = handlers; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setInterceptors(List<WxCpMessageInterceptor> interceptors) { | ||||||
|  |     this.interceptors = interceptors; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public boolean isAsync() { | ||||||
|  |     return async; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setAsync(boolean async) { | ||||||
|  |     this.async = async; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public boolean isReEnter() { | ||||||
|  |     return reEnter; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setReEnter(boolean reEnter) { | ||||||
|  |     this.reEnter = reEnter; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -1,6 +1,5 @@ | |||||||
| 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.InternalSession; | import me.chanjar.weixin.common.session.InternalSession; | ||||||
| import me.chanjar.weixin.common.session.InternalSessionManager; | import me.chanjar.weixin.common.session.InternalSessionManager; | ||||||
| import me.chanjar.weixin.common.session.StandardSessionManager; | import me.chanjar.weixin.common.session.StandardSessionManager; | ||||||
| @ -15,14 +14,11 @@ import org.slf4j.Logger; | |||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; |  | ||||||
| import java.util.concurrent.ExecutionException; | 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.concurrent.Future; | ||||||
| import java.util.regex.Pattern; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * <pre> |  * <pre> | ||||||
| @ -30,8 +26,8 @@ import java.util.regex.Pattern; | |||||||
|  *  |  *  | ||||||
|  * 说明: |  * 说明: | ||||||
|  * 1. 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理 |  * 1. 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理 | ||||||
|  * 2. 默认情况下消息只会被处理一次,除非使用 {@link Rule#next()} |  * 2. 默认情况下消息只会被处理一次,除非使用 {@link WxMpMessageRouterRule#next()} | ||||||
|  * 3. 规则的结束必须用{@link Rule#end()}或者{@link Rule#next()},否则不会生效 |  * 3. 规则的结束必须用{@link WxMpMessageRouterRule#end()}或者{@link WxMpMessageRouterRule#next()},否则不会生效 | ||||||
|  *  |  *  | ||||||
|  * 使用方法: |  * 使用方法: | ||||||
|  * WxMpMessageRouter router = new WxMpMessageRouter(); |  * WxMpMessageRouter router = new WxMpMessageRouter(); | ||||||
| @ -49,6 +45,8 @@ import java.util.regex.Pattern; | |||||||
|  * router.route(message); |  * router.route(message); | ||||||
|  *  |  *  | ||||||
|  * </pre> |  * </pre> | ||||||
|  |  * @author Daniel Qian | ||||||
|  |  * | ||||||
|  */ |  */ | ||||||
| public class WxMpMessageRouter { | public class WxMpMessageRouter { | ||||||
|  |  | ||||||
| @ -56,7 +54,7 @@ public class WxMpMessageRouter { | |||||||
|  |  | ||||||
|   private static final int DEFAULT_THREAD_POOL_SIZE = 100; |   private static final int DEFAULT_THREAD_POOL_SIZE = 100; | ||||||
|  |  | ||||||
|   private final List<Rule> rules = new ArrayList<Rule>(); |   private final List<WxMpMessageRouterRule> rules = new ArrayList<WxMpMessageRouterRule>(); | ||||||
|  |  | ||||||
|   private final WxMpService wxMpService; |   private final WxMpService wxMpService; | ||||||
|  |  | ||||||
| @ -101,7 +99,7 @@ public class WxMpMessageRouter { | |||||||
|   /** |   /** | ||||||
|    * <pre> |    * <pre> | ||||||
|    * 设置自定义的{@link me.chanjar.weixin.common.session.WxSessionManager} |    * 设置自定义的{@link me.chanjar.weixin.common.session.WxSessionManager} | ||||||
|    * 如果不调用该方法,默认使用 {@linke SessionManagerImpl} |    * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.session.StandardSessionManager} | ||||||
|    * </pre> |    * </pre> | ||||||
|    * @param sessionManager |    * @param sessionManager | ||||||
|    */ |    */ | ||||||
| @ -109,12 +107,27 @@ public class WxMpMessageRouter { | |||||||
|     this.sessionManager = sessionManager; |     this.sessionManager = sessionManager; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * <pre> | ||||||
|  |    * 设置自定义的{@link me.chanjar.weixin.common.util.WxErrorExceptionHandler} | ||||||
|  |    * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.LogExceptionHandler} | ||||||
|  |    * </pre> | ||||||
|  |    * @param exceptionHandler | ||||||
|  |    */ | ||||||
|  |   public void setExceptionHandler(WxErrorExceptionHandler exceptionHandler) { | ||||||
|  |     this.exceptionHandler = exceptionHandler; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   List<WxMpMessageRouterRule> getRules() { | ||||||
|  |     return this.rules; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 开始一个新的Route规则 |    * 开始一个新的Route规则 | ||||||
|    * @return |    * @return | ||||||
|    */ |    */ | ||||||
|   public Rule rule() { |   public WxMpMessageRouterRule rule() { | ||||||
|     return new Rule(this); |     return new WxMpMessageRouterRule(this); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @ -127,12 +140,12 @@ public class WxMpMessageRouter { | |||||||
|       return null; |       return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     final List<Rule> matchRules = new ArrayList<Rule>(); |     final List<WxMpMessageRouterRule> matchRules = new ArrayList<WxMpMessageRouterRule>(); | ||||||
|     // 收集匹配的规则 |     // 收集匹配的规则 | ||||||
|     for (final Rule rule : rules) { |     for (final WxMpMessageRouterRule rule : rules) { | ||||||
|       if (rule.test(wxMessage)) { |       if (rule.test(wxMessage)) { | ||||||
|         matchRules.add(rule); |         matchRules.add(rule); | ||||||
|         if(!rule.reEnter) { |         if(!rule.isReEnter()) { | ||||||
|           break; |           break; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @ -144,9 +157,9 @@ public class WxMpMessageRouter { | |||||||
|  |  | ||||||
|     WxMpXmlOutMessage res = null; |     WxMpXmlOutMessage res = null; | ||||||
|     final List<Future> futures = new ArrayList<Future>(); |     final List<Future> futures = new ArrayList<Future>(); | ||||||
|     for (final Rule rule : matchRules) { |     for (final WxMpMessageRouterRule rule : matchRules) { | ||||||
|       // 返回最后一个非异步的rule的执行结果 |       // 返回最后一个非异步的rule的执行结果 | ||||||
|       if(rule.async) { |       if(rule.isAsync()) { | ||||||
|         futures.add( |         futures.add( | ||||||
|             executorService.submit(new Runnable() { |             executorService.submit(new Runnable() { | ||||||
|               public void run() { |               public void run() { | ||||||
| @ -215,237 +228,4 @@ public class WxMpMessageRouter { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public static class Rule { |  | ||||||
|      |  | ||||||
|     private final WxMpMessageRouter routerBuilder; |  | ||||||
|  |  | ||||||
|     private boolean async = true; |  | ||||||
|  |  | ||||||
|     private String fromUser; |  | ||||||
|      |  | ||||||
|     private String msgType; |  | ||||||
|  |  | ||||||
|     private String event; |  | ||||||
|      |  | ||||||
|     private String eventKey; |  | ||||||
|      |  | ||||||
|     private String content; |  | ||||||
|      |  | ||||||
|     private String rContent; |  | ||||||
|  |  | ||||||
|     private WxMpMessageMatcher matcher; |  | ||||||
|  |  | ||||||
|     private boolean reEnter = false; |  | ||||||
|      |  | ||||||
|     private List<WxMpMessageHandler> handlers = new ArrayList<WxMpMessageHandler>(); |  | ||||||
|      |  | ||||||
|     private List<WxMpMessageInterceptor> interceptors = new ArrayList<WxMpMessageInterceptor>(); |  | ||||||
|  |  | ||||||
|     protected Rule(WxMpMessageRouter routerBuilder) { |  | ||||||
|       this.routerBuilder = routerBuilder; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 设置是否异步执行,默认是true |  | ||||||
|      * @param async |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule async(boolean async) { |  | ||||||
|       this.async = async; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 如果msgType等于某值 |  | ||||||
|      * @param msgType |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule msgType(String msgType) { |  | ||||||
|       this.msgType = msgType; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 如果event等于某值 |  | ||||||
|      * @param event |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule event(String event) { |  | ||||||
|       this.event = event; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 如果eventKey等于某值 |  | ||||||
|      * @param eventKey |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule eventKey(String eventKey) { |  | ||||||
|       this.eventKey = eventKey; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 如果content等于某值 |  | ||||||
|      * @param content |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule content(String content) { |  | ||||||
|       this.content = content; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 如果content匹配该正则表达式 |  | ||||||
|      * @param regex |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule rContent(String regex) { |  | ||||||
|       this.rContent = regex; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 如果fromUser等于某值 |  | ||||||
|      * @param fromUser |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule fromUser(String fromUser) { |  | ||||||
|       this.fromUser = fromUser; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 如果消息匹配某个matcher,用在用户需要自定义更复杂的匹配规则的时候 |  | ||||||
|      * @param matcher |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule matcher(WxMpMessageMatcher matcher) { |  | ||||||
|       this.matcher = matcher; |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 设置微信消息拦截器 |  | ||||||
|      * @param interceptor |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule interceptor(WxMpMessageInterceptor interceptor) { |  | ||||||
|       return interceptor(interceptor, (WxMpMessageInterceptor[]) null); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 设置微信消息拦截器 |  | ||||||
|      * @param interceptor |  | ||||||
|      * @param otherInterceptors |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule interceptor(WxMpMessageInterceptor interceptor, WxMpMessageInterceptor... otherInterceptors) { |  | ||||||
|       this.interceptors.add(interceptor); |  | ||||||
|       if (otherInterceptors != null && otherInterceptors.length > 0) { |  | ||||||
|         for (WxMpMessageInterceptor i : otherInterceptors) { |  | ||||||
|           this.interceptors.add(i); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 设置微信消息处理器 |  | ||||||
|      * @param handler |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule handler(WxMpMessageHandler handler) { |  | ||||||
|       return handler(handler, (WxMpMessageHandler[]) null); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 设置微信消息处理器 |  | ||||||
|      * @param handler |  | ||||||
|      * @param otherHandlers |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public Rule handler(WxMpMessageHandler handler, WxMpMessageHandler... otherHandlers) { |  | ||||||
|       this.handlers.add(handler); |  | ||||||
|       if (otherHandlers != null && otherHandlers.length > 0) { |  | ||||||
|         for (WxMpMessageHandler i : otherHandlers) { |  | ||||||
|           this.handlers.add(i); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       return this; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 规则结束,代表如果一个消息匹配该规则,那么它将不再会进入其他规则 |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public WxMpMessageRouter end() { |  | ||||||
|       this.routerBuilder.rules.add(this); |  | ||||||
|       return this.routerBuilder; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 规则结束,但是消息还会进入其他规则 |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public WxMpMessageRouter next() { |  | ||||||
|       this.reEnter = true; |  | ||||||
|       return end(); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     protected boolean test(WxMpXmlMessage wxMessage) { |  | ||||||
|       return |  | ||||||
|           (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName())) |  | ||||||
|           && |  | ||||||
|           (this.msgType == null || this.msgType.equals(wxMessage.getMsgType())) |  | ||||||
|           && |  | ||||||
|           (this.event == null || this.event.equals(wxMessage.getEvent())) |  | ||||||
|           && |  | ||||||
|           (this.eventKey == null || this.eventKey.equals(wxMessage.getEventKey())) |  | ||||||
|           && |  | ||||||
|           (this.content == null || this.content.equals(wxMessage.getContent() == null ? null : wxMessage.getContent().trim())) |  | ||||||
|           && |  | ||||||
|           (this.rContent == null || Pattern.matches(this.rContent, wxMessage.getContent() == null ? "" : wxMessage.getContent().trim())) |  | ||||||
|           && |  | ||||||
|           (this.matcher == null || this.matcher.match(wxMessage)) |  | ||||||
|       ; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 处理微信推送过来的消息 |  | ||||||
|      * @param wxMessage |  | ||||||
|      * @return true 代表继续执行别的router,false 代表停止执行别的router |  | ||||||
|      */ |  | ||||||
|     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); |  | ||||||
|       } |  | ||||||
|       return null; |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|   } |  | ||||||
|    |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,353 @@ | |||||||
|  | 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.util.WxErrorExceptionHandler; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | ||||||
|  | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.regex.Pattern; | ||||||
|  |  | ||||||
|  | public class WxMpMessageRouterRule { | ||||||
|  |  | ||||||
|  |   private final WxMpMessageRouter routerBuilder; | ||||||
|  |  | ||||||
|  |   private boolean async = true; | ||||||
|  |  | ||||||
|  |   private String fromUser; | ||||||
|  |  | ||||||
|  |   private String msgType; | ||||||
|  |  | ||||||
|  |   private String event; | ||||||
|  |  | ||||||
|  |   private String eventKey; | ||||||
|  |  | ||||||
|  |   private String content; | ||||||
|  |  | ||||||
|  |   private String rContent; | ||||||
|  |  | ||||||
|  |   private WxMpMessageMatcher matcher; | ||||||
|  |  | ||||||
|  |   private boolean reEnter = false; | ||||||
|  |  | ||||||
|  |   private List<WxMpMessageHandler> handlers = new ArrayList<WxMpMessageHandler>(); | ||||||
|  |  | ||||||
|  |   private List<WxMpMessageInterceptor> interceptors = new ArrayList<WxMpMessageInterceptor>(); | ||||||
|  |  | ||||||
|  |   public WxMpMessageRouterRule(WxMpMessageRouter routerBuilder) { | ||||||
|  |     this.routerBuilder = routerBuilder; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 设置是否异步执行,默认是true | ||||||
|  |    * | ||||||
|  |    * @param async | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule async(boolean async) { | ||||||
|  |     this.async = async; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果msgType等于某值 | ||||||
|  |    * | ||||||
|  |    * @param msgType | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule msgType(String msgType) { | ||||||
|  |     this.msgType = msgType; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果event等于某值 | ||||||
|  |    * | ||||||
|  |    * @param event | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule event(String event) { | ||||||
|  |     this.event = event; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果eventKey等于某值 | ||||||
|  |    * | ||||||
|  |    * @param eventKey | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule eventKey(String eventKey) { | ||||||
|  |     this.eventKey = eventKey; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果content等于某值 | ||||||
|  |    * | ||||||
|  |    * @param content | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule content(String content) { | ||||||
|  |     this.content = content; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果content匹配该正则表达式 | ||||||
|  |    * | ||||||
|  |    * @param regex | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule rContent(String regex) { | ||||||
|  |     this.rContent = regex; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果fromUser等于某值 | ||||||
|  |    * | ||||||
|  |    * @param fromUser | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule fromUser(String fromUser) { | ||||||
|  |     this.fromUser = fromUser; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 如果消息匹配某个matcher,用在用户需要自定义更复杂的匹配规则的时候 | ||||||
|  |    * | ||||||
|  |    * @param matcher | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule matcher(WxMpMessageMatcher matcher) { | ||||||
|  |     this.matcher = matcher; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 设置微信消息拦截器 | ||||||
|  |    * | ||||||
|  |    * @param interceptor | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule interceptor(WxMpMessageInterceptor interceptor) { | ||||||
|  |     return interceptor(interceptor, (WxMpMessageInterceptor[]) null); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 设置微信消息拦截器 | ||||||
|  |    * | ||||||
|  |    * @param interceptor | ||||||
|  |    * @param otherInterceptors | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule interceptor(WxMpMessageInterceptor interceptor, WxMpMessageInterceptor... otherInterceptors) { | ||||||
|  |     this.interceptors.add(interceptor); | ||||||
|  |     if (otherInterceptors != null && otherInterceptors.length > 0) { | ||||||
|  |       for (WxMpMessageInterceptor i : otherInterceptors) { | ||||||
|  |         this.interceptors.add(i); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 设置微信消息处理器 | ||||||
|  |    * | ||||||
|  |    * @param handler | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule handler(WxMpMessageHandler handler) { | ||||||
|  |     return handler(handler, (WxMpMessageHandler[]) null); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 设置微信消息处理器 | ||||||
|  |    * | ||||||
|  |    * @param handler | ||||||
|  |    * @param otherHandlers | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouterRule handler(WxMpMessageHandler handler, WxMpMessageHandler... otherHandlers) { | ||||||
|  |     this.handlers.add(handler); | ||||||
|  |     if (otherHandlers != null && otherHandlers.length > 0) { | ||||||
|  |       for (WxMpMessageHandler i : otherHandlers) { | ||||||
|  |         this.handlers.add(i); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 规则结束,代表如果一个消息匹配该规则,那么它将不再会进入其他规则 | ||||||
|  |    * | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouter end() { | ||||||
|  |     this.routerBuilder.getRules().add(this); | ||||||
|  |     return this.routerBuilder; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 规则结束,但是消息还会进入其他规则 | ||||||
|  |    * | ||||||
|  |    * @return | ||||||
|  |    */ | ||||||
|  |   public WxMpMessageRouter next() { | ||||||
|  |     this.reEnter = true; | ||||||
|  |     return end(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   protected boolean test(WxMpXmlMessage wxMessage) { | ||||||
|  |     return | ||||||
|  |         (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName())) | ||||||
|  |             && | ||||||
|  |             (this.msgType == null || this.msgType.equals(wxMessage.getMsgType())) | ||||||
|  |             && | ||||||
|  |             (this.event == null || this.event.equals(wxMessage.getEvent())) | ||||||
|  |             && | ||||||
|  |             (this.eventKey == null || this.eventKey.equals(wxMessage.getEventKey())) | ||||||
|  |             && | ||||||
|  |             (this.content == null || this.content | ||||||
|  |                 .equals(wxMessage.getContent() == null ? null : wxMessage.getContent().trim())) | ||||||
|  |             && | ||||||
|  |             (this.rContent == null || Pattern | ||||||
|  |                 .matches(this.rContent, wxMessage.getContent() == null ? "" : wxMessage.getContent().trim())) | ||||||
|  |             && | ||||||
|  |             (this.matcher == null || this.matcher.match(wxMessage)) | ||||||
|  |         ; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 处理微信推送过来的消息 | ||||||
|  |    * | ||||||
|  |    * @param wxMessage | ||||||
|  |    * @return true 代表继续执行别的router,false 代表停止执行别的router | ||||||
|  |    */ | ||||||
|  |   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); | ||||||
|  |     } | ||||||
|  |     return null; | ||||||
|  |  | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public WxMpMessageRouter getRouterBuilder() { | ||||||
|  |     return routerBuilder; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public boolean isAsync() { | ||||||
|  |     return async; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setAsync(boolean async) { | ||||||
|  |     this.async = async; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getFromUser() { | ||||||
|  |     return fromUser; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setFromUser(String fromUser) { | ||||||
|  |     this.fromUser = fromUser; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getMsgType() { | ||||||
|  |     return msgType; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setMsgType(String msgType) { | ||||||
|  |     this.msgType = msgType; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getEvent() { | ||||||
|  |     return event; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setEvent(String event) { | ||||||
|  |     this.event = event; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getEventKey() { | ||||||
|  |     return eventKey; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setEventKey(String eventKey) { | ||||||
|  |     this.eventKey = eventKey; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getContent() { | ||||||
|  |     return content; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setContent(String content) { | ||||||
|  |     this.content = content; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public String getrContent() { | ||||||
|  |     return rContent; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setrContent(String rContent) { | ||||||
|  |     this.rContent = rContent; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public WxMpMessageMatcher getMatcher() { | ||||||
|  |     return matcher; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setMatcher(WxMpMessageMatcher matcher) { | ||||||
|  |     this.matcher = matcher; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public boolean isReEnter() { | ||||||
|  |     return reEnter; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setReEnter(boolean reEnter) { | ||||||
|  |     this.reEnter = reEnter; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public List<WxMpMessageHandler> getHandlers() { | ||||||
|  |     return handlers; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setHandlers(List<WxMpMessageHandler> handlers) { | ||||||
|  |     this.handlers = handlers; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public List<WxMpMessageInterceptor> getInterceptors() { | ||||||
|  |     return interceptors; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setInterceptors(List<WxMpMessageInterceptor> interceptors) { | ||||||
|  |     this.interceptors = interceptors; | ||||||
|  |   } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Daniel Qian
					Daniel Qian