From f6b1f76210668ad81459850b91b4737f3aab986b Mon Sep 17 00:00:00 2001 From: jinyu Date: Wed, 24 Jun 2015 20:57:24 +0800 Subject: [PATCH] =?UTF-8?q?weixin4j-qy:=20=E6=96=B0=E5=A2=9Euserid?= =?UTF-8?q?=E4=B8=8Eopenid=E4=BA=92=E6=8D=A2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGE.md | 6 +- .../weixin4j/xml/ListsuffixResult.java | 7 +- .../xml/ListsuffixResultDeserializer.java | 27 ++++++- weixin4j-qy/CHANGE.md | 6 +- .../com/foxinmy/weixin4j/qy/WeixinProxy.java | 35 +++++++++ .../com/foxinmy/weixin4j/qy/api/UserApi.java | 52 ++++++++++++- .../foxinmy/weixin4j/qy/api/weixin.properties | 6 +- .../foxinmy/weixin4j/qy/test/UserTest.java | 7 ++ .../dispatcher/MessageHandlerExecutor.java | 16 +++- .../dispatcher/WeixinMessageDispatcher.java | 38 +++++++--- .../weixin4j/handler/BlankMessageHandler.java | 10 ++- .../weixin4j/handler/DebugMessageHandler.java | 10 ++- .../handler/MessageHandlerAdapter.java | 10 ++- .../handler/WeixinMessageHandler.java | 16 ++-- .../MessageInterceptorAdapter.java | 11 ++- .../interceptor/WeixinMessageInterceptor.java | 17 ++++- .../weixin4j/socket/WeixinRequestHandler.java | 13 ++-- .../socket/WeixinServerInitializer.java | 2 +- .../weixin4j/suite/SuiteEventType.java | 26 ------- .../weixin4j/suite/SuiteMessageHandler.java | 23 ------ .../weixin4j/suite/WeixinSuiteMessage.java | 76 ------------------- .../weixin4j/xml/CruxMessageHandler.java | 23 +++++- .../server/test/MessageServerStartup.java | 13 ++-- 23 files changed, 255 insertions(+), 195 deletions(-) delete mode 100644 weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/SuiteEventType.java delete mode 100644 weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/SuiteMessageHandler.java delete mode 100644 weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/WeixinSuiteMessage.java diff --git a/CHANGE.md b/CHANGE.md index d8689ad3..aa700ec1 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -347,4 +347,8 @@ + **weixin4j-mp**: 新增企业付款查询接口 - + **weixin4j-server**: 对多个公众号的接入支持 \ No newline at end of file + + **weixin4j-server**: 对多个公众号的接入支持 + +* 2015-06-24 + + + **weixin4j-qy**: 新增userid与openid互换接口 \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/ListsuffixResult.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/ListsuffixResult.java index c79fec14..4a0d97b4 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/ListsuffixResult.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/ListsuffixResult.java @@ -4,7 +4,6 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.util.regex.Pattern; /** * 对$n结尾的节点注解 @@ -18,9 +17,5 @@ import java.util.regex.Pattern; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ListsuffixResult { - String[] value() default { DEFAULT_REGEX }; - - public final static String DEFAULT_REGEX = "(_\\d)$"; - public final static Pattern DEFAULT_PATTERN = Pattern - .compile(DEFAULT_REGEX); + String[] value() default { "(_\\d)$" }; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/ListsuffixResultDeserializer.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/ListsuffixResultDeserializer.java index c7506d5c..88ffea86 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/ListsuffixResultDeserializer.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/ListsuffixResultDeserializer.java @@ -42,6 +42,26 @@ import com.foxinmy.weixin4j.util.StringUtil; */ public class ListsuffixResultDeserializer { + private static Pattern DEFAULT_PATTERN; + static { + String regex = null; + try { + Object value = ListsuffixResult.class.getMethod("value") + .getDefaultValue(); + if (value instanceof String) { + regex = (String) value; + } else if (value instanceof String[]) { + regex = ((String[]) value)[0]; + } + } catch (NoSuchMethodException e) { + ; + } + if (StringUtil.isBlank(regex)) { + regex = "(_\\d)$"; + } + DEFAULT_PATTERN = Pattern.compile(regex); + } + /** * 对包含$n节点的xml序列化 * @@ -109,9 +129,8 @@ public class ListsuffixResultDeserializer { } else if (event == XMLStreamConstants.CHARACTERS) { String key = matcher.group(); if (!pattern.pattern().equals( - ListsuffixResult.DEFAULT_REGEX)) { - matcher = ListsuffixResult.DEFAULT_PATTERN - .matcher(name); + DEFAULT_PATTERN.pattern())) { + matcher = DEFAULT_PATTERN.matcher(name); matcher.find(); key = matcher.group(); } @@ -146,7 +165,7 @@ public class ListsuffixResultDeserializer { .getDefaultValue().toString())) { itemName = rootElement.name(); } - } catch (Exception e) { + } catch (NoSuchMethodException e) { ; } } diff --git a/weixin4j-qy/CHANGE.md b/weixin4j-qy/CHANGE.md index c28ab7ec..e36e42dd 100644 --- a/weixin4j-qy/CHANGE.md +++ b/weixin4j-qy/CHANGE.md @@ -60,4 +60,8 @@ * 2015-06-22 - + 新增企业号[第三方应用代理](src/main/java/com/foxinmy/weixin4j/qy/WeixinSuiteProxy.java)。 \ No newline at end of file + + 新增企业号[第三方应用代理](src/main/java/com/foxinmy/weixin4j/qy/WeixinSuiteProxy.java)。 + +* 2015-06-24 + + + 新增userid与openid互换接口 \ No newline at end of file diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java index 5f46f651..adfb6408 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java @@ -851,4 +851,39 @@ public class WeixinProxy { public BatchResult getresult(String jobId) throws WeixinException { return batchApi.getresult(jobId); } + + /** + * userid转换成openid:该接口使用场景为微信支付、微信红包和企业转账,企业号用户在使用微信支付的功能时, + * 需要自行将企业号的userid转成openid。 在使用微信红包功能时,需要将应用id和userid转成appid和openid才能使用。 + * + * @param userid + * 企业号内的成员id 必填 + * @param agentid + * 需要发送红包的应用ID,若只是使用微信支付和企业转账,则无需该参数 传入0或负数则忽略 + * @return 结果数组 第一个元素为对应的openid 第二个元素则为应用的appid(如果有) + * @throws WeixinException + * @see com.foxinmy.weixin4j.qy.api.UserApi + * @see userid转换成openid + */ + public String[] userid2openid(String userid, int agentid) + throws WeixinException { + return userApi.userid2openid(userid, agentid); + } + + /** + * openid转换成userid:该接口主要应用于使用微信支付、微信红包和企业转账之后的结果查询, + * 开发者需要知道某个结果事件的openid对应企业号内成员的信息时,可以通过调用该接口进行转换查询。 + * + * @param openid + * 在使用微信支付、微信红包和企业转账之后,返回结果的openid + * @return 该openid在企业号中对应的成员userid + * @throws WeixinException + * @see com.foxinmy.weixin4j.qy.api.UserApi + * @see openid转换成userid + */ + public String openid2userid(String openid) throws WeixinException { + return userApi.openid2userid(openid); + } } diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/UserApi.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/UserApi.java index 015e0fee..f421dff3 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/UserApi.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/UserApi.java @@ -15,7 +15,6 @@ import com.foxinmy.weixin4j.qy.model.User; import com.foxinmy.weixin4j.qy.type.InviteType; import com.foxinmy.weixin4j.qy.type.UserStatus; import com.foxinmy.weixin4j.token.TokenHolder; -import com.foxinmy.weixin4j.util.StringUtil; /** * 成员API @@ -304,9 +303,7 @@ public class UserApi extends QyApi { throws WeixinException { JSONObject obj = new JSONObject(); obj.put("userid", userId); - if (StringUtil.isBlank(tips)) { - obj.put("invite_tips", tips); - } + obj.put("invite_tips", tips); String invite_user_uri = getRequestUri("invite_user_uri"); Token token = tokenHolder.getToken(); WeixinResponse response = weixinClient.post( @@ -321,4 +318,51 @@ public class UserApi extends QyApi { return null; } } + + /** + * userid转换成openid:该接口使用场景为微信支付、微信红包和企业转账,企业号用户在使用微信支付的功能时, + * 需要自行将企业号的userid转成openid。 在使用微信红包功能时,需要将应用id和userid转成appid和openid才能使用。 + * + * @param userid + * 企业号内的成员id 必填 + * @param agentid + * 需要发送红包的应用ID,若只是使用微信支付和企业转账,则无需该参数 传入0或负数则忽略 + * @return 结果数组 第一个元素为对应的openid 第二个元素则为应用的appid(如果有) + * @throws WeixinException + * @see userid转换成openid + */ + public String[] userid2openid(String userid, int agentid) + throws WeixinException { + JSONObject obj = new JSONObject(); + obj.put("userid", userid); + if (agentid > 0) { + obj.put("agentid", agentid); + } + String userid2openid_uri = getRequestUri("userid2openid_uri"); + WeixinResponse response = weixinClient.post( + String.format(userid2openid_uri, tokenHolder.getAccessToken()), + obj.toJSONString()); + obj = response.getAsJson(); + return new String[] { obj.getString("openid"), obj.getString("appid") }; + } + + /** + * openid转换成userid:该接口主要应用于使用微信支付、微信红包和企业转账之后的结果查询, + * 开发者需要知道某个结果事件的openid对应企业号内成员的信息时,可以通过调用该接口进行转换查询。 + * + * @param openid + * 在使用微信支付、微信红包和企业转账之后,返回结果的openid + * @return 该openid在企业号中对应的成员userid + * @throws WeixinException + * @see openid转换成userid + */ + public String openid2userid(String openid) throws WeixinException { + String openid2userid_uri = getRequestUri("openid2userid_uri"); + WeixinResponse response = weixinClient.post( + String.format(openid2userid_uri, tokenHolder.getAccessToken()), + String.format("{\"openid\": \"%s\"}", openid)); + return response.getAsJson().getString("userid"); + } } diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties index 43fc813d..47092838 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties @@ -95,4 +95,8 @@ suite_get_authinfo_uri={api_base_url}/service/get_auth_info?suite_access_token=% # \u83b7\u53d6\u4f01\u4e1a\u53f7\u5e94\u7528 suite_get_agent_uri={api_base_url}/service/get_agent?suite_access_token=%s # \u8bbe\u7f6e\u4f01\u4e1a\u53f7\u5e94\u7528 -suite_set_agent_uri={api_base_url}/service/set_agent?suite_access_token=%s \ No newline at end of file +suite_set_agent_uri={api_base_url}/service/set_agent?suite_access_token=%s +# userid\u8f6c\u6362\u6210openid +userid2openid_uri={api_base_url}/user/convert_to_openid?access_token=%s +# openid\u8f6c\u6362\u6210userid +openid2userid_uri={api_base_url}/user/convert_to_userid?access_token=%s \ No newline at end of file diff --git a/weixin4j-qy/src/test/java/com/foxinmy/weixin4j/qy/test/UserTest.java b/weixin4j-qy/src/test/java/com/foxinmy/weixin4j/qy/test/UserTest.java index 9588c25c..a4d8cdbf 100644 --- a/weixin4j-qy/src/test/java/com/foxinmy/weixin4j/qy/test/UserTest.java +++ b/weixin4j-qy/src/test/java/com/foxinmy/weixin4j/qy/test/UserTest.java @@ -89,4 +89,11 @@ public class UserTest extends TokenTest { public void invite() throws WeixinException { userApi.inviteUser("11", null); } + + @Test + public void convert() throws WeixinException { + String[] result = userApi.userid2openid("jinyu", 1); + System.err.println(result); + System.err.println(userApi.openid2userid(result[0])); + } } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/MessageHandlerExecutor.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/MessageHandlerExecutor.java index db0c080e..24ae7f67 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/MessageHandlerExecutor.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/MessageHandlerExecutor.java @@ -4,6 +4,8 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; +import java.util.Set; + import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.handler.WeixinMessageHandler; import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor; @@ -33,16 +35,22 @@ public class MessageHandlerExecutor { * 消息拦截器 */ private final WeixinMessageInterceptor[] messageInterceptors; + /** + * 节点名称集合 + */ + private final Set nodeNames; private final ChannelHandlerContext context; private int interceptorIndex = -1; public MessageHandlerExecutor(ChannelHandlerContext context, WeixinMessageHandler messageHandler, - WeixinMessageInterceptor[] messageInterceptors) { + WeixinMessageInterceptor[] messageInterceptors, + Set nodeNames) { this.context = context; this.messageHandler = messageHandler; this.messageInterceptors = messageInterceptors; + this.nodeNames = nodeNames; } public WeixinMessageHandler getMessageHandler() { @@ -65,7 +73,7 @@ public class MessageHandlerExecutor { for (int i = 0; i < messageInterceptors.length; i++) { WeixinMessageInterceptor interceptor = messageInterceptors[i]; if (!interceptor.preHandle(context, request, message, - messageHandler)) { + nodeNames, messageHandler)) { triggerAfterCompletion(request, message, null); return false; } @@ -94,7 +102,7 @@ public class MessageHandlerExecutor { for (int i = messageInterceptors.length - 1; i >= 0; i--) { WeixinMessageInterceptor interceptor = messageInterceptors[i]; interceptor.postHandle(context, request, response, message, - messageHandler); + nodeNames, messageHandler); } } @@ -118,7 +126,7 @@ public class MessageHandlerExecutor { WeixinMessageInterceptor interceptor = messageInterceptors[i]; try { interceptor.afterCompletion(context, request, message, - messageHandler, exception); + nodeNames, messageHandler, exception); } catch (WeixinException e) { logger.error( "MessageInterceptor.afterCompletion threw exception", e); diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java index b8513d11..82d1eb17 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java @@ -15,6 +15,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; @@ -29,6 +30,7 @@ import com.foxinmy.weixin4j.handler.WeixinMessageHandler; import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor; import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.response.WeixinResponse; +import com.foxinmy.weixin4j.type.AccountType; import com.foxinmy.weixin4j.util.ClassUtil; import com.foxinmy.weixin4j.util.Consts; import com.foxinmy.weixin4j.util.HttpUtil; @@ -110,17 +112,16 @@ public class WeixinMessageDispatcher { public void doDispatch(final ChannelHandlerContext context, final WeixinRequest request, final CruxMessageHandler cruxMessage) throws WeixinException { - MessageKey messageKey = new MessageKey(cruxMessage.getMsgType(), + MessageKey messageKey = defineMessageKey(cruxMessage.getMsgType(), cruxMessage.getEventType(), cruxMessage.getAccountType()); Class targetClass = messageMatcher.match(messageKey); Object message = request.getOriginalContent(); if (targetClass != null) { message = messageRead(request.getOriginalContent(), targetClass); } - logger.info("define '{}' matched '{}'", messageKey, - targetClass); + logger.info("define '{}' matched '{}'", messageKey, targetClass); MessageHandlerExecutor handlerExecutor = getHandlerExecutor(context, - request, messageKey, message); + request, messageKey, message, cruxMessage.getNodeNames()); if (handlerExecutor == null || handlerExecutor.getMessageHandler() == null) { noHandlerFound(context, request, message); @@ -132,7 +133,7 @@ public class WeixinMessageDispatcher { WeixinException dispatchException = null; try { WeixinResponse response = handlerExecutor.getMessageHandler() - .doHandle(request, message); + .doHandle(request, message, cruxMessage.getNodeNames()); handlerExecutor.applyPostHandle(request, response, message); context.write(response); } catch (WeixinException e) { @@ -142,6 +143,22 @@ public class WeixinMessageDispatcher { dispatchException); } + /** + * 声明messagekey + * + * @param messageType + * 消息类型 + * @param eventType + * 事件类型 + * @param accountType + * 账号类型 + * @return + */ + protected MessageKey defineMessageKey(String messageType, String eventType, + AccountType accountType) { + return new MessageKey(messageType, eventType, accountType); + } + /** * 未匹配到handler时触发 * @@ -170,13 +187,16 @@ public class WeixinMessageDispatcher { * 消息的key * @param message * 微信消息 + * @param nodeNames + * 节点名称集合 * @return MessageHandlerExecutor * @see com.foxinmy.weixin4j.dispatcher.MessageHandlerExecutor * @throws WeixinException */ protected MessageHandlerExecutor getHandlerExecutor( ChannelHandlerContext context, WeixinRequest request, - MessageKey messageKey, Object message) throws WeixinException { + MessageKey messageKey, Object message, Set nodeNames) + throws WeixinException { WeixinMessageHandler messageHandler = null; WeixinMessageHandler[] messageHandlers = getMessageHandlers(); if (messageHandlers == null) { @@ -186,7 +206,7 @@ public class WeixinMessageDispatcher { if (handler instanceof MessageHandlerAdapter) { Class genericType = genericTypeRead(handler); if (genericType == message.getClass() - && handler.canHandle(request, message)) { + && handler.canHandle(request, message, nodeNames)) { messageHandler = handler; break; } @@ -195,14 +215,14 @@ public class WeixinMessageDispatcher { if (messageHandler == null) { for (WeixinMessageHandler handler : messageHandlers) { if (!(handler instanceof MessageHandlerAdapter) - && handler.canHandle(request, message)) { + && handler.canHandle(request, message, nodeNames)) { messageHandler = handler; break; } } } return new MessageHandlerExecutor(context, messageHandler, - getMessageInterceptors()); + getMessageInterceptors(), nodeNames); } /** diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/BlankMessageHandler.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/BlankMessageHandler.java index 0eef64c0..048d1a02 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/BlankMessageHandler.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/BlankMessageHandler.java @@ -1,5 +1,7 @@ package com.foxinmy.weixin4j.handler; +import java.util.Set; + import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.response.BlankResponse; @@ -23,14 +25,14 @@ public class BlankMessageHandler implements WeixinMessageHandler { } @Override - public boolean canHandle(WeixinRequest request, Object message) - throws WeixinException { + public boolean canHandle(WeixinRequest request, Object message, + Set nodeNames) throws WeixinException { return true; } @Override - public WeixinResponse doHandle(WeixinRequest request, Object message) - throws WeixinException { + public WeixinResponse doHandle(WeixinRequest request, Object message, + Set nodeNames) throws WeixinException { return BlankResponse.global; } } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/DebugMessageHandler.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/DebugMessageHandler.java index 00679b71..109e24b7 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/DebugMessageHandler.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/DebugMessageHandler.java @@ -1,5 +1,7 @@ package com.foxinmy.weixin4j.handler; +import java.util.Set; + import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.response.TextResponse; @@ -23,14 +25,14 @@ public class DebugMessageHandler implements WeixinMessageHandler { } @Override - public boolean canHandle(WeixinRequest request, Object message) - throws WeixinException { + public boolean canHandle(WeixinRequest request, Object message, + Set nodeNames) throws WeixinException { return true; } @Override - public WeixinResponse doHandle(WeixinRequest request, Object message) - throws WeixinException { + public WeixinResponse doHandle(WeixinRequest request, Object message, + Set nodeNames) throws WeixinException { return new TextResponse(message.toString()); } } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/MessageHandlerAdapter.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/MessageHandlerAdapter.java index fe7ddd78..6155ce86 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/MessageHandlerAdapter.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/MessageHandlerAdapter.java @@ -1,5 +1,7 @@ package com.foxinmy.weixin4j.handler; +import java.util.Set; + import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.response.WeixinResponse; @@ -17,8 +19,8 @@ import com.foxinmy.weixin4j.response.WeixinResponse; public abstract class MessageHandlerAdapter implements WeixinMessageHandler { @Override - public boolean canHandle(WeixinRequest request, Object message) - throws WeixinException { + public boolean canHandle(WeixinRequest request, Object message, + Set nodeNames) throws WeixinException { return canHandle0(request, (M) message); } @@ -38,8 +40,8 @@ public abstract class MessageHandlerAdapter implements WeixinMessageHandler { } @Override - public WeixinResponse doHandle(WeixinRequest request, Object message) - throws WeixinException { + public WeixinResponse doHandle(WeixinRequest request, Object message, + Set nodeNames) throws WeixinException { return doHandle0(request, (M) message); } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/WeixinMessageHandler.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/WeixinMessageHandler.java index 58fa9a65..dac049f1 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/WeixinMessageHandler.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/handler/WeixinMessageHandler.java @@ -1,5 +1,7 @@ package com.foxinmy.weixin4j.handler; +import java.util.Set; + import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.response.WeixinResponse; @@ -22,10 +24,12 @@ public interface WeixinMessageHandler { * 微信请求 * @param message * 微信消息 + * @param nodeNames + * 节点名称集合 * @return true则执行doHandle */ - public boolean canHandle(WeixinRequest request, Object message) - throws WeixinException; + public boolean canHandle(WeixinRequest request, Object message, + Set nodeNames) throws WeixinException; /** * 处理请求 @@ -34,8 +38,10 @@ public interface WeixinMessageHandler { * 微信请求 * @param message * 微信消息 - * @return + * @param nodeNames + * 节点名称集合 + * @return 回复内容 */ - public WeixinResponse doHandle(WeixinRequest request, Object message) - throws WeixinException; + public WeixinResponse doHandle(WeixinRequest request, Object message, + Set nodeNames) throws WeixinException; } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/interceptor/MessageInterceptorAdapter.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/interceptor/MessageInterceptorAdapter.java index 50881d56..89f98df2 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/interceptor/MessageInterceptorAdapter.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/interceptor/MessageInterceptorAdapter.java @@ -2,6 +2,8 @@ package com.foxinmy.weixin4j.interceptor; import io.netty.channel.ChannelHandlerContext; +import java.util.Set; + import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.handler.WeixinMessageHandler; import com.foxinmy.weixin4j.request.WeixinRequest; @@ -21,20 +23,21 @@ public abstract class MessageInterceptorAdapter implements @Override public boolean preHandle(ChannelHandlerContext context, - WeixinRequest request, Object message, WeixinMessageHandler handler) - throws WeixinException { + WeixinRequest request, Object message, Set nodeNames, + WeixinMessageHandler handler) throws WeixinException { return true; } @Override public void postHandle(ChannelHandlerContext context, WeixinRequest request, WeixinResponse response, Object message, - WeixinMessageHandler handler) throws WeixinException { + Set nodeNames, WeixinMessageHandler handler) + throws WeixinException { } @Override public void afterCompletion(ChannelHandlerContext context, - WeixinRequest request, Object message, + WeixinRequest request, Object message, Set nodeNames, WeixinMessageHandler handler, WeixinException exception) throws WeixinException { } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/interceptor/WeixinMessageInterceptor.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/interceptor/WeixinMessageInterceptor.java index 5721f9da..7e59a41c 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/interceptor/WeixinMessageInterceptor.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/interceptor/WeixinMessageInterceptor.java @@ -2,6 +2,8 @@ package com.foxinmy.weixin4j.interceptor; import io.netty.channel.ChannelHandlerContext; +import java.util.Set; + import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.handler.WeixinMessageHandler; import com.foxinmy.weixin4j.request.WeixinRequest; @@ -27,13 +29,15 @@ public interface WeixinMessageInterceptor { * 微信请求 * @param message * 微信消息 + * @param nodeNames + * 节点名称集合 * @param handler * 消息处理器 * @return 返回true执行下一个拦截器 * @throws WeixinException */ boolean preHandle(ChannelHandlerContext context, WeixinRequest request, - Object message, WeixinMessageHandler handler) + Object message, Set nodeNames, WeixinMessageHandler handler) throws WeixinException; /** @@ -47,12 +51,14 @@ public interface WeixinMessageInterceptor { * 微信响应 * @param message * 微信消息 + * @param nodeNames + * 节点名称集合 * @param handler * 消息处理器 * @throws WeixinException */ void postHandle(ChannelHandlerContext context, WeixinRequest request, - WeixinResponse response, Object message, + WeixinResponse response, Object message, Set nodeNames, WeixinMessageHandler handler) throws WeixinException; /** @@ -64,6 +70,8 @@ public interface WeixinMessageInterceptor { * 微信请求 * @param message * 微信消息 + * @param nodeNames + * 节点名称集合 * @param handler * 消息处理器 * @param exception @@ -71,6 +79,7 @@ public interface WeixinMessageInterceptor { * @throws WeixinException */ void afterCompletion(ChannelHandlerContext context, WeixinRequest request, - Object message, WeixinMessageHandler handler, - WeixinException exception) throws WeixinException; + Object message, Set nodeNames, + WeixinMessageHandler handler, WeixinException exception) + throws WeixinException; } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinRequestHandler.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinRequestHandler.java index b99c9d8d..3a97e8db 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinRequestHandler.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinRequestHandler.java @@ -18,6 +18,7 @@ import com.foxinmy.weixin4j.util.AesToken; import com.foxinmy.weixin4j.util.Consts; import com.foxinmy.weixin4j.util.HttpUtil; import com.foxinmy.weixin4j.util.MessageUtil; +import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.xml.CruxMessageHandler; /** @@ -36,8 +37,7 @@ public class WeixinRequestHandler extends private final WeixinMessageDispatcher messageDispatcher; - public WeixinRequestHandler(WeixinMessageDispatcher messageDispatcher) - throws WeixinException { + public WeixinRequestHandler(WeixinMessageDispatcher messageDispatcher) { this.messageDispatcher = messageDispatcher; } @@ -70,9 +70,10 @@ public class WeixinRequestHandler extends .addListener(ChannelFutureListener.CLOSE); return; } else if (request.getMethod().equals(HttpMethod.POST.name())) { - if (!MessageUtil.signature(aesToken.getToken(), - request.getTimeStamp(), request.getNonce()).equals( - request.getSignature())) { + if (!StringUtil.isBlank(request.getSignature()) + && !MessageUtil.signature(aesToken.getToken(), + request.getTimeStamp(), request.getNonce()).equals( + request.getSignature())) { ctx.writeAndFlush( HttpUtil.createHttpResponse(null, FORBIDDEN, null)) .addListener(ChannelFutureListener.CLOSE); @@ -103,4 +104,6 @@ public class WeixinRequestHandler extends ctx.channel().attr(Consts.MESSAGE_TRANSFER_KEY).set(messageTransfer); messageDispatcher.doDispatch(ctx, request, cruxMessage); } + + } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinServerInitializer.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinServerInitializer.java index 386af7be..849bfe03 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinServerInitializer.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinServerInitializer.java @@ -36,7 +36,7 @@ public class WeixinServerInitializer extends ChannelInitializer { } @Override - protected void initChannel(SocketChannel channel) throws WeixinException { + protected void initChannel(SocketChannel channel) { ChannelPipeline pipeline = channel.pipeline(); pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new HttpObjectAggregator(65536)); diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/SuiteEventType.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/SuiteEventType.java deleted file mode 100644 index 0e57bc6a..00000000 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/SuiteEventType.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.foxinmy.weixin4j.suite; - -/** - * 应用套件回调事件 - * - * @className SuiteEventType - * @author jy - * @date 2015年6月21日 - * @since JDK 1.7 - * @see 第三方回调协议 - */ -public enum SuiteEventType { - /** - * 推送ticket - */ - suite_ticket, - /** - * 变更授权 - */ - change_auth, - /** - * 取消授权 - */ - cancel_auth; -} diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/SuiteMessageHandler.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/SuiteMessageHandler.java deleted file mode 100644 index 1fa269c9..00000000 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/SuiteMessageHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.foxinmy.weixin4j.suite; - -import com.foxinmy.weixin4j.response.SingleResponse; - -/** - * 处理第三方应用套件请求 - * - * @className SuiteMessageHandler - * @author jy - * @date 2015年6月23日 - * @since JDK 1.7 - * @see 套件回调协议 - */ -public interface SuiteMessageHandler { - /** - * 处理套件消息 - * - * @param suiteMessage - * @return - */ - public SingleResponse handle(WeixinSuiteMessage suiteMessage); -} diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/WeixinSuiteMessage.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/WeixinSuiteMessage.java deleted file mode 100644 index 7bcf9451..00000000 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/suite/WeixinSuiteMessage.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.foxinmy.weixin4j.suite; - -import java.io.Serializable; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -/** - * 套件消息 - * - * @className WeixinSuiteMessage - * @author jy - * @date 2015年6月23日 - * @since JDK 1.7 - * @see - */ -@XmlRootElement(name = "xml") -@XmlAccessorType(XmlAccessType.FIELD) -public class WeixinSuiteMessage implements Serializable { - - private static final long serialVersionUID = 6457919241019021514L; - /** - * 应用套件的SuiteId - */ - @XmlElement(name = "SuiteId") - private String suiteId; - /** - * 事件类型 - */ - @XmlElement(name = "InfoType") - private SuiteEventType eventType; - /** - * 时间戳 - */ - @XmlElement(name = "TimeStamp") - private long timeStamp; - /** - * Ticket内容 - */ - @XmlElement(name = "SuiteTicket") - private String SuiteTicket; - /** - * 授权方企业号的corpid - */ - @XmlElement(name = "AuthCorpId") - private String authCorpId; - - public String getSuiteId() { - return suiteId; - } - - public SuiteEventType getEventType() { - return eventType; - } - - public long getTimeStamp() { - return timeStamp; - } - - public String getSuiteTicket() { - return SuiteTicket; - } - - public String getAuthCorpId() { - return authCorpId; - } - - @Override - public String toString() { - return "WeixinSuiteMessage [suiteId=" + suiteId + ", eventType=" - + eventType + ", timeStamp=" + timeStamp + ", SuiteTicket=" - + SuiteTicket + ", authCorpId=" + authCorpId + "]"; - } -} diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/xml/CruxMessageHandler.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/xml/CruxMessageHandler.java index 9e18091d..5a9eb5c6 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/xml/CruxMessageHandler.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/xml/CruxMessageHandler.java @@ -2,6 +2,8 @@ package com.foxinmy.weixin4j.xml; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.util.HashSet; +import java.util.Set; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -28,7 +30,8 @@ public class CruxMessageHandler extends DefaultHandler { private String toUserName; private String msgType; private String eventType; - private String agentId; + private boolean agentId; + private Set nodeNames; private String content; @@ -38,12 +41,14 @@ public class CruxMessageHandler extends DefaultHandler { toUserName = null; msgType = null; eventType = null; - agentId = null; + agentId = false; + nodeNames = new HashSet(); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { + nodeNames.add(localName.toLowerCase()); if (localName.equalsIgnoreCase("fromUserName")) { fromUserName = content; } else if (localName.equalsIgnoreCase("toUserName")) { @@ -53,7 +58,7 @@ public class CruxMessageHandler extends DefaultHandler { } else if (localName.equalsIgnoreCase("event")) { eventType = content.toLowerCase(); } else if (localName.equalsIgnoreCase("agentId")) { - agentId = content; + agentId = true; } } @@ -64,7 +69,13 @@ public class CruxMessageHandler extends DefaultHandler { } public AccountType getAccountType() { - return StringUtil.isBlank(agentId) ? AccountType.MP : AccountType.QY; + if (agentId) { + return AccountType.QY; + } + if (StringUtil.isBlank(msgType) && StringUtil.isBlank(eventType)) { + return null; + } + return AccountType.MP; } public String getMsgType() { @@ -83,6 +94,10 @@ public class CruxMessageHandler extends DefaultHandler { return toUserName; } + public Set getNodeNames() { + return nodeNames; + } + private static CruxMessageHandler global = new CruxMessageHandler(); public static CruxMessageHandler parser(String xmlContent) diff --git a/weixin4j-server/src/test/java/com/foxinmy/weixin4j/server/test/MessageServerStartup.java b/weixin4j-server/src/test/java/com/foxinmy/weixin4j/server/test/MessageServerStartup.java index 20043800..2031f5d9 100644 --- a/weixin4j-server/src/test/java/com/foxinmy/weixin4j/server/test/MessageServerStartup.java +++ b/weixin4j-server/src/test/java/com/foxinmy/weixin4j/server/test/MessageServerStartup.java @@ -2,6 +2,8 @@ package com.foxinmy.weixin4j.server.test; import io.netty.channel.ChannelHandlerContext; +import java.util.Set; + import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.handler.BlankMessageHandler; import com.foxinmy.weixin4j.handler.DebugMessageHandler; @@ -88,7 +90,8 @@ public class MessageServerStartup { @Override public boolean preHandle(ChannelHandlerContext context, WeixinRequest request, Object message, - WeixinMessageHandler handler) throws WeixinException { + Set nodeNames, WeixinMessageHandler handler) + throws WeixinException { context.writeAndFlush(new TextResponse("所有消息被拦截了!")); return false; } @@ -96,16 +99,16 @@ public class MessageServerStartup { @Override public void postHandle(ChannelHandlerContext context, WeixinRequest request, WeixinResponse response, - Object message, WeixinMessageHandler handler) - throws WeixinException { + Object message, Set nodeNames, + WeixinMessageHandler handler) throws WeixinException { System.err.println("preHandle返回为true,执行handler后"); } @Override public void afterCompletion(ChannelHandlerContext context, WeixinRequest request, Object message, - WeixinMessageHandler handler, WeixinException exception) - throws WeixinException { + Set nodeNames, WeixinMessageHandler handler, + WeixinException exception) throws WeixinException { System.err.println("请求处理完毕"); } };