11package me .chanjar .weixin .cp .api ;
22
3- import me .chanjar .weixin .common .exception .WxErrorException ;
4- import me .chanjar .weixin .common .session .*;
3+ import me .chanjar .weixin .common .session .InternalSession ;
4+ import me .chanjar .weixin .common .session .InternalSessionManager ;
5+ import me .chanjar .weixin .common .session .StandardSessionManager ;
6+ import me .chanjar .weixin .common .session .WxSessionManager ;
57import me .chanjar .weixin .common .util .LogExceptionHandler ;
68import me .chanjar .weixin .common .util .WxErrorExceptionHandler ;
79import me .chanjar .weixin .common .util .WxMessageDuplicateChecker ;
1214import org .slf4j .LoggerFactory ;
1315
1416import java .util .ArrayList ;
15- import java .util .HashMap ;
1617import java .util .List ;
17- import java .util .Map ;
1818import java .util .concurrent .ExecutionException ;
1919import java .util .concurrent .ExecutorService ;
2020import java .util .concurrent .Executors ;
2121import java .util .concurrent .Future ;
22- import java .util .regex .Pattern ;
2322
2423/**
2524 * <pre>
2625 * 微信消息路由器,通过代码化的配置,把来自微信的消息交给handler处理
2726 *
2827 * 说明:
2928 * 1. 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理
30- * 2. 默认情况下消息只会被处理一次,除非使用 {@link Rule #next()}
31- * 3. 规则的结束必须用{@link Rule #end()}或者{@link Rule #next()},否则不会生效
29+ * 2. 默认情况下消息只会被处理一次,除非使用 {@link WxCpMessageRouterRule #next()}
30+ * 3. 规则的结束必须用{@link WxCpMessageRouterRule #end()}或者{@link WxCpMessageRouterRule #next()},否则不会生效
3231 *
3332 * 使用方法:
3433 * WxCpMessageRouter router = new WxCpMessageRouter();
@@ -55,7 +54,7 @@ public class WxCpMessageRouter {
5554
5655 private static final int DEFAULT_THREAD_POOL_SIZE = 100 ;
5756
58- private final List <Rule > rules = new ArrayList <Rule >();
57+ private final List <WxCpMessageRouterRule > rules = new ArrayList <WxCpMessageRouterRule >();
5958
6059 private final WxCpService wxCpService ;
6160
@@ -100,20 +99,35 @@ public void setMessageDuplicateChecker(WxMessageDuplicateChecker messageDuplicat
10099 /**
101100 * <pre>
102101 * 设置自定义的{@link me.chanjar.weixin.common.session.WxSessionManager}
103- * 如果不调用该方法,默认使用 {@linke SessionManagerImpl }
102+ * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.session.StandardSessionManager }
104103 * </pre>
105104 * @param sessionManager
106105 */
107106 public void setSessionManager (WxSessionManager sessionManager ) {
108107 this .sessionManager = sessionManager ;
109108 }
110109
110+ /**
111+ * <pre>
112+ * 设置自定义的{@link me.chanjar.weixin.common.util.WxErrorExceptionHandler}
113+ * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.LogExceptionHandler}
114+ * </pre>
115+ * @param exceptionHandler
116+ */
117+ public void setExceptionHandler (WxErrorExceptionHandler exceptionHandler ) {
118+ this .exceptionHandler = exceptionHandler ;
119+ }
120+
121+ List <WxCpMessageRouterRule > getRules () {
122+ return this .rules ;
123+ }
124+
111125 /**
112126 * 开始一个新的Route规则
113127 * @return
114128 */
115- public Rule rule () {
116- return new Rule (this );
129+ public WxCpMessageRouterRule rule () {
130+ return new WxCpMessageRouterRule (this );
117131 }
118132
119133 /**
@@ -125,13 +139,13 @@ public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage) {
125139 // 如果是重复消息,那么就不做处理
126140 return null ;
127141 }
128-
129- final List <Rule > matchRules = new ArrayList <Rule >();
142+
143+ final List <WxCpMessageRouterRule > matchRules = new ArrayList <WxCpMessageRouterRule >();
130144 // 收集匹配的规则
131- for (final Rule rule : rules ) {
145+ for (final WxCpMessageRouterRule rule : rules ) {
132146 if (rule .test (wxMessage )) {
133147 matchRules .add (rule );
134- if (!rule .reEnter ) {
148+ if (!rule .isReEnter () ) {
135149 break ;
136150 }
137151 }
@@ -143,9 +157,9 @@ public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage) {
143157
144158 WxCpXmlOutMessage res = null ;
145159 final List <Future > futures = new ArrayList <Future >();
146- for (final Rule rule : matchRules ) {
160+ for (final WxCpMessageRouterRule rule : matchRules ) {
147161 // 返回最后一个非异步的rule的执行结果
148- if (rule .async ) {
162+ if (rule .isAsync () ) {
149163 futures .add (
150164 executorService .submit (new Runnable () {
151165 public void run () {
@@ -216,252 +230,5 @@ protected void sessionEndAccess(WxCpXmlMessage wxMessage) {
216230
217231 }
218232
219- public static class Rule {
220-
221- private final WxCpMessageRouter routerBuilder ;
222-
223- private boolean async = true ;
224-
225- private String fromUser ;
226-
227- private String msgType ;
228-
229- private String event ;
230-
231- private String eventKey ;
232-
233- private String content ;
234-
235- private String rContent ;
236-
237- private WxCpMessageMatcher matcher ;
238-
239- private boolean reEnter = false ;
240-
241- private Integer agentId ;
242-
243- private List <WxCpMessageHandler > handlers = new ArrayList <WxCpMessageHandler >();
244-
245- private List <WxCpMessageInterceptor > interceptors = new ArrayList <WxCpMessageInterceptor >();
246-
247- protected Rule (WxCpMessageRouter routerBuilder ) {
248- this .routerBuilder = routerBuilder ;
249- }
250-
251- /**
252- * 设置是否异步执行,默认是true
253- * @param async
254- * @return
255- */
256- public Rule async (boolean async ) {
257- this .async = async ;
258- return this ;
259- }
260-
261- /**
262- * 如果agentId匹配
263- * @param agentId
264- * @return
265- */
266- public Rule agentId (Integer agentId ) {
267- this .agentId = agentId ;
268- return this ;
269- }
270-
271- /**
272- * 如果msgType等于某值
273- * @param msgType
274- * @return
275- */
276- public Rule msgType (String msgType ) {
277- this .msgType = msgType ;
278- return this ;
279- }
280-
281- /**
282- * 如果event等于某值
283- * @param event
284- * @return
285- */
286- public Rule event (String event ) {
287- this .event = event ;
288- return this ;
289- }
290-
291- /**
292- * 如果eventKey等于某值
293- * @param eventKey
294- * @return
295- */
296- public Rule eventKey (String eventKey ) {
297- this .eventKey = eventKey ;
298- return this ;
299- }
300-
301- /**
302- * 如果content等于某值
303- * @param content
304- * @return
305- */
306- public Rule content (String content ) {
307- this .content = content ;
308- return this ;
309- }
310-
311- /**
312- * 如果content匹配该正则表达式
313- * @param regex
314- * @return
315- */
316- public Rule rContent (String regex ) {
317- this .rContent = regex ;
318- return this ;
319- }
320-
321- /**
322- * 如果fromUser等于某值
323- * @param fromUser
324- * @return
325- */
326- public Rule fromUser (String fromUser ) {
327- this .fromUser = fromUser ;
328- return this ;
329- }
330-
331- /**
332- * 如果消息匹配某个matcher,用在用户需要自定义更复杂的匹配规则的时候
333- * @param matcher
334- * @return
335- */
336- public Rule matcher (WxCpMessageMatcher matcher ) {
337- this .matcher = matcher ;
338- return this ;
339- }
340-
341- /**
342- * 设置微信消息拦截器
343- * @param interceptor
344- * @return
345- */
346- public Rule interceptor (WxCpMessageInterceptor interceptor ) {
347- return interceptor (interceptor , (WxCpMessageInterceptor []) null );
348- }
349-
350- /**
351- * 设置微信消息拦截器
352- * @param interceptor
353- * @param otherInterceptors
354- * @return
355- */
356- public Rule interceptor (WxCpMessageInterceptor interceptor , WxCpMessageInterceptor ... otherInterceptors ) {
357- this .interceptors .add (interceptor );
358- if (otherInterceptors != null && otherInterceptors .length > 0 ) {
359- for (WxCpMessageInterceptor i : otherInterceptors ) {
360- this .interceptors .add (i );
361- }
362- }
363- return this ;
364- }
365-
366- /**
367- * 设置微信消息处理器
368- * @param handler
369- * @return
370- */
371- public Rule handler (WxCpMessageHandler handler ) {
372- return handler (handler , (WxCpMessageHandler []) null );
373- }
374-
375- /**
376- * 设置微信消息处理器
377- * @param handler
378- * @param otherHandlers
379- * @return
380- */
381- public Rule handler (WxCpMessageHandler handler , WxCpMessageHandler ... otherHandlers ) {
382- this .handlers .add (handler );
383- if (otherHandlers != null && otherHandlers .length > 0 ) {
384- for (WxCpMessageHandler i : otherHandlers ) {
385- this .handlers .add (i );
386- }
387- }
388- return this ;
389- }
390-
391- /**
392- * 规则结束,代表如果一个消息匹配该规则,那么它将不再会进入其他规则
393- * @return
394- */
395- public WxCpMessageRouter end () {
396- this .routerBuilder .rules .add (this );
397- return this .routerBuilder ;
398- }
399-
400- /**
401- * 规则结束,但是消息还会进入其他规则
402- * @return
403- */
404- public WxCpMessageRouter next () {
405- this .reEnter = true ;
406- return end ();
407- }
408-
409- protected boolean test (WxCpXmlMessage wxMessage ) {
410- return
411- (this .fromUser == null || this .fromUser .equals (wxMessage .getFromUserName ()))
412- &&
413- (this .agentId == null || this .agentId .equals (wxMessage .getAgentId ()))
414- &&
415- (this .msgType == null || this .msgType .equals (wxMessage .getMsgType ()))
416- &&
417- (this .event == null || this .event .equals (wxMessage .getEvent ()))
418- &&
419- (this .eventKey == null || this .eventKey .equals (wxMessage .getEventKey ()))
420- &&
421- (this .content == null || this .content .equals (wxMessage .getContent () == null ? null : wxMessage .getContent ().trim ()))
422- &&
423- (this .rContent == null || Pattern .matches (this .rContent , wxMessage .getContent () == null ? "" : wxMessage .getContent ().trim ()))
424- &&
425- (this .matcher == null || this .matcher .match (wxMessage ))
426- ;
427- }
428-
429- /**
430- * 处理微信推送过来的消息
431- * @param wxMessage
432- * @return true 代表继续执行别的router,false 代表停止执行别的router
433- */
434- protected WxCpXmlOutMessage service (WxCpXmlMessage wxMessage ,
435- WxCpService wxCpService ,
436- WxSessionManager sessionManager ,
437- WxErrorExceptionHandler exceptionHandler ) {
438-
439- try {
440-
441- Map <String , Object > context = new HashMap <String , Object >();
442- // 如果拦截器不通过
443- for (WxCpMessageInterceptor interceptor : this .interceptors ) {
444- if (!interceptor .intercept (wxMessage , context , wxCpService , sessionManager )) {
445- return null ;
446- }
447- }
448-
449- // 交给handler处理
450- WxCpXmlOutMessage res = null ;
451- for (WxCpMessageHandler handler : this .handlers ) {
452- // 返回最后handler的结果
453- res = handler .handle (wxMessage , context , wxCpService , sessionManager );
454- }
455- return res ;
456-
457- } catch (WxErrorException e ) {
458- exceptionHandler .handle (e );
459- }
460-
461- return null ;
462-
463- }
464-
465- }
466233
467234}
0 commit comments