新增MultipleMessageHandlerAdapter多个消息适配类

This commit is contained in:
jinyu 2016-03-12 18:05:36 +08:00
parent 64c95c2903
commit 5a9d5b61d3
11 changed files with 107 additions and 47 deletions

View File

@ -135,3 +135,10 @@
* 2015-02-04 * 2015-02-04
+ version upgrade to 1.1.6 + version upgrade to 1.1.6
* 2015-03-12
+ 修改ClassUtil获取class不到的bug
+ 新增MultipleMessageHandlerAdapter多个消息适配类

View File

@ -1,5 +1,7 @@
package com.foxinmy.weixin4j.dispatcher; package com.foxinmy.weixin4j.dispatcher;
import java.util.Map;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
/** /**
@ -17,4 +19,6 @@ public interface BeanFactory {
<T> T getBean(Class<T> clazz) throws WeixinException; <T> T getBean(Class<T> clazz) throws WeixinException;
<T> T getBean(String name, Class<T> clazz) throws WeixinException; <T> T getBean(String name, Class<T> clazz) throws WeixinException;
<T> Map<String, T> getBeans(Class<T> clazz) throws WeixinException;
} }

View File

@ -7,6 +7,7 @@ import io.netty.util.internal.logging.InternalLoggerFactory;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.handler.WeixinMessageHandler; import com.foxinmy.weixin4j.handler.WeixinMessageHandler;
import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor; import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.WeixinResponse; import com.foxinmy.weixin4j.response.WeixinResponse;
@ -62,7 +63,7 @@ public class MessageHandlerExecutor {
* @return true则继续执行往下执行 * @return true则继续执行往下执行
* @throws WeixinException * @throws WeixinException
*/ */
public boolean applyPreHandle(WeixinRequest request, Object message) public boolean applyPreHandle(WeixinRequest request, WeixinMessage message)
throws WeixinException { throws WeixinException {
if (messageInterceptors != null) { if (messageInterceptors != null) {
for (int i = 0; i < messageInterceptors.length; i++) { for (int i = 0; i < messageInterceptors.length; i++) {
@ -90,7 +91,7 @@ public class MessageHandlerExecutor {
* @throws WeixinException * @throws WeixinException
*/ */
public void applyPostHandle(WeixinRequest request, WeixinResponse response, public void applyPostHandle(WeixinRequest request, WeixinResponse response,
Object message) throws WeixinException { WeixinMessage message) throws WeixinException {
if (messageInterceptors == null) { if (messageInterceptors == null) {
return; return;
} }
@ -115,7 +116,7 @@ public class MessageHandlerExecutor {
* @throws WeixinException * @throws WeixinException
*/ */
public void triggerAfterCompletion(WeixinRequest request, public void triggerAfterCompletion(WeixinRequest request,
WeixinResponse response, Object message, Exception exception) WeixinResponse response, WeixinMessage message, Exception exception)
throws WeixinException { throws WeixinException {
if (messageInterceptors == null) { if (messageInterceptors == null) {
return; return;

View File

@ -125,7 +125,7 @@ public class WeixinMessageDispatcher {
WeixinMessageKey messageKey = defineMessageKey(messageTransfer, request); WeixinMessageKey messageKey = defineMessageKey(messageTransfer, request);
Class<? extends WeixinMessage> targetClass = messageMatcher Class<? extends WeixinMessage> targetClass = messageMatcher
.match(messageKey); .match(messageKey);
Object message = messageRead(request.getOriginalContent(), targetClass); WeixinMessage message = messageRead(request.getOriginalContent(), targetClass);
logger.info("define '{}' matched '{}'", messageKey, targetClass); logger.info("define '{}' matched '{}'", messageKey, targetClass);
MessageHandlerExecutor handlerExecutor = getHandlerExecutor(context, MessageHandlerExecutor handlerExecutor = getHandlerExecutor(context,
request, messageKey, message, messageTransfer.getNodeNames()); request, messageKey, message, messageTransfer.getNodeNames());
@ -209,17 +209,17 @@ public class WeixinMessageDispatcher {
*/ */
protected MessageHandlerExecutor getHandlerExecutor( protected MessageHandlerExecutor getHandlerExecutor(
ChannelHandlerContext context, WeixinRequest request, ChannelHandlerContext context, WeixinRequest request,
WeixinMessageKey messageKey, Object message, Set<String> nodeNames) WeixinMessageKey messageKey, WeixinMessage message, Set<String> nodeNames)
throws WeixinException { throws WeixinException {
WeixinMessageHandler[] messageHandlers = getMessageHandlers(); WeixinMessageHandler[] messageHandlers = getMessageHandlers();
if (messageHandlers == null) { if (messageHandlers == null) {
return null; return null;
} }
logger.info("resolve handlers '{}'", this.messageHandlerList);
List<WeixinMessageHandler> matchedMessageHandlers = new ArrayList<WeixinMessageHandler>(); List<WeixinMessageHandler> matchedMessageHandlers = new ArrayList<WeixinMessageHandler>();
for (WeixinMessageHandler handler : messageHandlers) { for (WeixinMessageHandler handler : messageHandlers) {
if (handler.canHandle(request, message, nodeNames)) { if (handler.canHandle(request, message, nodeNames)) {
matchedMessageHandlers.add(handler); matchedMessageHandlers.add(handler);
break;
} }
} }
if (matchedMessageHandlers.isEmpty()) { if (matchedMessageHandlers.isEmpty()) {
@ -233,6 +233,7 @@ public class WeixinMessageDispatcher {
return m2.weight() - m1.weight(); return m2.weight() - m1.weight();
} }
}); });
logger.info("matched message handlers '{}'", matchedMessageHandlers);
return new MessageHandlerExecutor(context, return new MessageHandlerExecutor(context,
matchedMessageHandlers.get(0), getMessageInterceptors()); matchedMessageHandlers.get(0), getMessageInterceptors());
} }
@ -254,9 +255,20 @@ public class WeixinMessageDispatcher {
} }
if (beanFactory != null) { if (beanFactory != null) {
for (Class<?> clazz : messageHandlerClass) { for (Class<?> clazz : messageHandlerClass) {
messageHandlerList try {
.add((WeixinMessageHandler) beanFactory messageHandlerList
.getBean(clazz)); .add((WeixinMessageHandler) beanFactory
.getBean(clazz));
} catch (RuntimeException ex) { // multiple
for (Object o : beanFactory.getBeans(clazz)
.values()) {
if (o.getClass() == clazz) {
messageHandlerList
.add((WeixinMessageHandler) o);
break;
}
}
}
} }
} else { } else {
for (Class<?> clazz : messageHandlerClass) { for (Class<?> clazz : messageHandlerClass) {
@ -305,9 +317,20 @@ public class WeixinMessageDispatcher {
} }
if (beanFactory != null) { if (beanFactory != null) {
for (Class<?> clazz : messageInterceptorClass) { for (Class<?> clazz : messageInterceptorClass) {
messageInterceptorList try {
.add((WeixinMessageInterceptor) beanFactory messageInterceptorList
.getBean(clazz)); .add((WeixinMessageInterceptor) beanFactory
.getBean(clazz));
} catch (RuntimeException ex) { // multiple
for (Object o : beanFactory.getBeans(clazz)
.values()) {
if (o.getClass() == clazz) {
messageInterceptorList
.add((WeixinMessageInterceptor) o);
break;
}
}
}
} }
} else { } else {
for (Class<?> clazz : messageInterceptorClass) { for (Class<?> clazz : messageInterceptorClass) {

View File

@ -3,6 +3,7 @@ package com.foxinmy.weixin4j.handler;
import java.util.Set; import java.util.Set;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.TextResponse; import com.foxinmy.weixin4j.response.TextResponse;
import com.foxinmy.weixin4j.response.WeixinResponse; import com.foxinmy.weixin4j.response.WeixinResponse;
@ -25,13 +26,13 @@ public class DebugMessageHandler implements WeixinMessageHandler {
} }
@Override @Override
public boolean canHandle(WeixinRequest request, Object message, public boolean canHandle(WeixinRequest request, WeixinMessage message,
Set<String> nodeNames) throws WeixinException { Set<String> nodeNames) throws WeixinException {
return true; return true;
} }
@Override @Override
public WeixinResponse doHandle(WeixinRequest request, Object message, public WeixinResponse doHandle(WeixinRequest request, WeixinMessage message,
Set<String> nodeNames) throws WeixinException { Set<String> nodeNames) throws WeixinException {
String content = message == null ? request.getOriginalContent() String content = message == null ? request.getOriginalContent()
.replaceAll("\\!\\[CDATA\\[", "").replaceAll("\\]\\]", "") .replaceAll("\\!\\[CDATA\\[", "").replaceAll("\\]\\]", "")

View File

@ -22,10 +22,10 @@ public abstract class MessageHandlerAdapter<M extends WeixinMessage> implements
WeixinMessageHandler { WeixinMessageHandler {
@Override @Override
public boolean canHandle(WeixinRequest request, Object message, public boolean canHandle(WeixinRequest request, WeixinMessage message,
Set<String> nodeNames) throws WeixinException { Set<String> nodeNames) throws WeixinException {
return message != null return message != null
&& message.getClass() == ClassUtil.getGenericType(this) && message.getClass() == ClassUtil.getGenericType(getClass())
&& canHandle0(request, (M) message); && canHandle0(request, (M) message);
} }
@ -36,7 +36,7 @@ public abstract class MessageHandlerAdapter<M extends WeixinMessage> implements
* 微信请求 * 微信请求
* @param message * @param message
* 微信消息 * 微信消息
* @return true则执行doHandler * @return true则执行doHandler0
* @throws WeixinException * @throws WeixinException
*/ */
public boolean canHandle0(WeixinRequest request, M message) public boolean canHandle0(WeixinRequest request, M message)
@ -45,8 +45,9 @@ public abstract class MessageHandlerAdapter<M extends WeixinMessage> implements
} }
@Override @Override
public WeixinResponse doHandle(WeixinRequest request, Object message, public WeixinResponse doHandle(WeixinRequest request,
Set<String> nodeNames) throws WeixinException { WeixinMessage message, Set<String> nodeNames)
throws WeixinException {
return doHandle0(request, (M) message); return doHandle0(request, (M) message);
} }

View File

@ -3,6 +3,7 @@ package com.foxinmy.weixin4j.handler;
import java.util.Set; import java.util.Set;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.WeixinResponse; import com.foxinmy.weixin4j.response.WeixinResponse;
@ -28,7 +29,7 @@ public interface WeixinMessageHandler {
* 节点名称集合 * 节点名称集合
* @return true则执行doHandle * @return true则执行doHandle
*/ */
public boolean canHandle(WeixinRequest request, Object message, public boolean canHandle(WeixinRequest request, WeixinMessage message,
Set<String> nodeNames) throws WeixinException; Set<String> nodeNames) throws WeixinException;
/** /**
@ -42,7 +43,7 @@ public interface WeixinMessageHandler {
* 节点名称集合 * 节点名称集合
* @return 回复内容 * @return 回复内容
*/ */
public WeixinResponse doHandle(WeixinRequest request, Object message, public WeixinResponse doHandle(WeixinRequest request, WeixinMessage message,
Set<String> nodeNames) throws WeixinException; Set<String> nodeNames) throws WeixinException;
/** /**

View File

@ -4,6 +4,7 @@ import io.netty.channel.ChannelHandlerContext;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.handler.WeixinMessageHandler; import com.foxinmy.weixin4j.handler.WeixinMessageHandler;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.WeixinResponse; import com.foxinmy.weixin4j.response.WeixinResponse;
@ -21,20 +22,20 @@ public abstract class MessageInterceptorAdapter implements
@Override @Override
public boolean preHandle(ChannelHandlerContext context, public boolean preHandle(ChannelHandlerContext context,
WeixinRequest request, Object message, WeixinMessageHandler handler) WeixinRequest request, WeixinMessage message, WeixinMessageHandler handler)
throws WeixinException { throws WeixinException {
return true; return true;
} }
@Override @Override
public void postHandle(ChannelHandlerContext context, public void postHandle(ChannelHandlerContext context,
WeixinRequest request, WeixinResponse response, Object message, WeixinRequest request, WeixinResponse response, WeixinMessage message,
WeixinMessageHandler handler) throws WeixinException { WeixinMessageHandler handler) throws WeixinException {
} }
@Override @Override
public void afterCompletion(ChannelHandlerContext context, public void afterCompletion(ChannelHandlerContext context,
WeixinRequest request, WeixinResponse response, Object message, WeixinRequest request, WeixinResponse response, WeixinMessage message,
WeixinMessageHandler handler, Exception exception) WeixinMessageHandler handler, Exception exception)
throws WeixinException { throws WeixinException {
} }

View File

@ -4,6 +4,7 @@ import io.netty.channel.ChannelHandlerContext;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.handler.WeixinMessageHandler; import com.foxinmy.weixin4j.handler.WeixinMessageHandler;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.WeixinResponse; import com.foxinmy.weixin4j.response.WeixinResponse;
@ -33,7 +34,7 @@ public interface WeixinMessageInterceptor {
* @throws WeixinException * @throws WeixinException
*/ */
boolean preHandle(ChannelHandlerContext context, WeixinRequest request, boolean preHandle(ChannelHandlerContext context, WeixinRequest request,
Object message, WeixinMessageHandler handler) WeixinMessage message, WeixinMessageHandler handler)
throws WeixinException; throws WeixinException;
/** /**
@ -52,7 +53,7 @@ public interface WeixinMessageInterceptor {
* @throws WeixinException * @throws WeixinException
*/ */
void postHandle(ChannelHandlerContext context, WeixinRequest request, void postHandle(ChannelHandlerContext context, WeixinRequest request,
WeixinResponse response, Object message, WeixinResponse response, WeixinMessage message,
WeixinMessageHandler handler) throws WeixinException; WeixinMessageHandler handler) throws WeixinException;
/** /**
@ -71,7 +72,7 @@ public interface WeixinMessageInterceptor {
* @throws WeixinException * @throws WeixinException
*/ */
void afterCompletion(ChannelHandlerContext context, WeixinRequest request, void afterCompletion(ChannelHandlerContext context, WeixinRequest request,
WeixinResponse response, Object message, WeixinResponse response, WeixinMessage message,
WeixinMessageHandler handler, Exception exception) WeixinMessageHandler handler, Exception exception)
throws WeixinException; throws WeixinException;

View File

@ -12,8 +12,8 @@ import java.lang.reflect.Type;
import java.net.JarURLConnection; import java.net.JarURLConnection;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
@ -75,7 +75,7 @@ public final class ClassUtil {
* @return * @return
*/ */
private static List<Class<?>> findClassesByFile(File dir, String packageName) { private static List<Class<?>> findClassesByFile(File dir, String packageName) {
List<Class<?>> classes = new LinkedList<Class<?>>(); List<Class<?>> classes = new ArrayList<Class<?>>();
File[] files = dir.listFiles(new FilenameFilter() { File[] files = dir.listFiles(new FilenameFilter() {
@Override @Override
public boolean accept(File file, String name) { public boolean accept(File file, String name) {
@ -111,23 +111,21 @@ public final class ClassUtil {
*/ */
private static List<Class<?>> findClassesByJar(JarFile jar, private static List<Class<?>> findClassesByJar(JarFile jar,
String packageName) { String packageName) {
List<Class<?>> classes = new LinkedList<Class<?>>(); List<Class<?>> classes = new ArrayList<Class<?>>();
Enumeration<JarEntry> jarEntries = jar.entries(); Enumeration<JarEntry> jarEntries = jar.entries();
while (jarEntries.hasMoreElements()) { while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement(); JarEntry jarEntry = jarEntries.nextElement();
if (jarEntry.isDirectory()) { if (jarEntry.isDirectory()) {
continue; continue;
} }
String entryName = jarEntry.getName(); String className = jarEntry.getName()
if (!entryName.startsWith(packageName)) { .replace(File.separator, POINT);
continue; if (!className.startsWith(packageName)
} || !className.endsWith(CLASS)) {
if (!entryName.endsWith(CLASS)) {
continue; continue;
} }
try { try {
classes.add(Class.forName(entryName.replace(File.separator, classes.add(Class.forName(className.replace(CLASS, "")));
POINT).replace(CLASS, "")));
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
; ;
} }
@ -177,15 +175,17 @@ public final class ClassUtil {
* @param object * @param object
* @return * @return
*/ */
public static Class<?> getGenericType(Object object) { public static Class<?> getGenericType(Class<?> clazz) {
Class<?> clazz = null; if(clazz == Object.class){
Type type = object.getClass().getGenericSuperclass(); return null;
}
Type type = clazz.getGenericSuperclass();
if (type instanceof ParameterizedType) { if (type instanceof ParameterizedType) {
ParameterizedType ptype = ((ParameterizedType) type); ParameterizedType ptype = ((ParameterizedType) type);
Type[] args = ptype.getActualTypeArguments(); Type[] args = ptype.getActualTypeArguments();
clazz = (Class<?>) args[0]; return (Class<?>) args[0];
} }
return clazz; return getGenericType(clazz.getSuperclass());
} }
public static ClassLoader getDefaultClassLoader() { public static ClassLoader getDefaultClassLoader() {

View File

@ -1,13 +1,18 @@
package com.foxinmy.weixin4j.server.test; package com.foxinmy.weixin4j.server.test;
import java.util.Set;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.handler.DebugMessageHandler; import com.foxinmy.weixin4j.handler.DebugMessageHandler;
import com.foxinmy.weixin4j.handler.MessageHandlerAdapter; import com.foxinmy.weixin4j.handler.MessageHandlerAdapter;
import com.foxinmy.weixin4j.handler.MultipleMessageHandlerAdapter;
import com.foxinmy.weixin4j.handler.WeixinMessageHandler; import com.foxinmy.weixin4j.handler.WeixinMessageHandler;
import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor; import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor;
import com.foxinmy.weixin4j.message.TextMessage; import com.foxinmy.weixin4j.message.TextMessage;
import com.foxinmy.weixin4j.mp.event.ScanEventMessage;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.TextResponse; import com.foxinmy.weixin4j.response.TextResponse;
import com.foxinmy.weixin4j.response.WeixinResponse; import com.foxinmy.weixin4j.response.WeixinResponse;
@ -84,7 +89,7 @@ public class MessageServerStartup {
WeixinMessageInterceptor interceptor = new WeixinMessageInterceptor() { WeixinMessageInterceptor interceptor = new WeixinMessageInterceptor() {
@Override @Override
public boolean preHandle(ChannelHandlerContext context, public boolean preHandle(ChannelHandlerContext context,
WeixinRequest request, Object message, WeixinRequest request, WeixinMessage message,
WeixinMessageHandler handler) throws WeixinException { WeixinMessageHandler handler) throws WeixinException {
context.writeAndFlush(new TextResponse("所有消息被拦截了!")); context.writeAndFlush(new TextResponse("所有消息被拦截了!"));
return false; return false;
@ -93,7 +98,7 @@ public class MessageServerStartup {
@Override @Override
public void postHandle(ChannelHandlerContext context, public void postHandle(ChannelHandlerContext context,
WeixinRequest request, WeixinResponse response, WeixinRequest request, WeixinResponse response,
Object message, WeixinMessageHandler handler) WeixinMessage message, WeixinMessageHandler handler)
throws WeixinException { throws WeixinException {
System.err.println("preHandle返回为true,执行handler后"); System.err.println("preHandle返回为true,执行handler后");
} }
@ -101,7 +106,7 @@ public class MessageServerStartup {
@Override @Override
public void afterCompletion(ChannelHandlerContext context, public void afterCompletion(ChannelHandlerContext context,
WeixinRequest request, WeixinResponse response, WeixinRequest request, WeixinResponse response,
Object message, WeixinMessageHandler handler, WeixinMessage message, WeixinMessageHandler handler,
Exception exception) throws WeixinException { Exception exception) throws WeixinException {
System.err.println("请求处理完毕"); System.err.println("请求处理完毕");
} }
@ -115,7 +120,22 @@ public class MessageServerStartup {
.openAlwaysResponse().startup(); .openAlwaysResponse().startup();
} }
@SuppressWarnings("unchecked")
public void test6() throws WeixinException {
MultipleMessageHandlerAdapter messageHandler = new MultipleMessageHandlerAdapter(
ScanEventMessage.class, TextMessage.class) {
@Override
public WeixinResponse doHandle(WeixinRequest request,
WeixinMessage message, Set<String> nodeNames)
throws WeixinException {
return new TextResponse("处理了扫描和文字消息");
}
};
new WeixinServerBootstrap(token).addHandler(messageHandler,
DebugMessageHandler.global).startup();
}
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
new MessageServerStartup().test1(); new MessageServerStartup().test6();
} }
} }