weixin4j-server:实现消息处理器的泛型自动匹配
This commit is contained in:
parent
b6ec2485c9
commit
67d87a0a69
@ -284,3 +284,7 @@
|
|||||||
* 2015-05-15
|
* 2015-05-15
|
||||||
|
|
||||||
+ **weixin4j-server**: 消息拦截器和处理器支持泛型
|
+ **weixin4j-server**: 消息拦截器和处理器支持泛型
|
||||||
|
|
||||||
|
* 2015-05-16
|
||||||
|
|
||||||
|
+ **weixin4j-server**: 实现消息处理器的泛型自动匹配
|
||||||
|
|||||||
@ -32,4 +32,8 @@
|
|||||||
|
|
||||||
* 2015-05-15
|
* 2015-05-15
|
||||||
|
|
||||||
+ **weixin4j-server**: 消息拦截器和处理器支持泛型
|
+ 消息拦截器和处理器支持泛型
|
||||||
|
|
||||||
|
* 2015-05-16
|
||||||
|
|
||||||
|
+ 实现消息处理器的泛型自动匹配
|
||||||
@ -37,23 +37,18 @@ weixin4j-server
|
|||||||
|
|
||||||
public class MessageServerStartup{
|
public class MessageServerStartup{
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// 需要一个文本消息的handler
|
// 针对文本消息回复
|
||||||
WeixinMessageHandler messageHandler = new WeixinMessageHandler() {
|
WeixinMessageHandler messageHandler = new MessageHandlerAdapter<TextMessage>() {
|
||||||
@Override
|
@Override
|
||||||
public WeixinResponse doHandle(WeixinRequest request,
|
public WeixinResponse doHandle0(WeixinRequest request,
|
||||||
WeixinMessage message) throws WeixinException {
|
TextMessage message) throws WeixinException {
|
||||||
return new TextResponse("HelloWorld!");
|
return new TextResponse("HelloWorld!");
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canHandle(WeixinRequest request,
|
|
||||||
WeixinMessage message) {
|
|
||||||
return message.getMsgType().equals("text");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 当消息类型为文本(text)时回复「HelloWorld」, 否则回复调试消息
|
// 当消息类型为文本(text)时回复「HelloWorld」, 否则回复调试消息
|
||||||
new WeixinServerBootstrap("appid","开发者token","加密密钥").addHandler(messageHandler,
|
new WeixinServerBootstrap(appid, token, aesKey).addHandler(
|
||||||
DebugMessageHandler.global).startup();
|
messageHandler, DebugMessageHandler.global).startup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
编写一个拦截器
|
编写一个拦截器
|
||||||
@ -63,22 +58,21 @@ weixin4j-server
|
|||||||
WeixinMessageInterceptor interceptor = new MessageInterceptorAdapter() {
|
WeixinMessageInterceptor interceptor = new MessageInterceptorAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean preHandle(ChannelHandlerContext context,
|
public boolean preHandle(ChannelHandlerContext context,
|
||||||
WeixinRequest request, WeixinMessage message,
|
WeixinRequest request, Object message,
|
||||||
WeixinMessageHandler handler) throws WeixinException {
|
WeixinMessageHandler handler) throws WeixinException {
|
||||||
context.write(new TextResponse("所有消息被拦截了!"));
|
context.write(new TextResponse("所有消息被拦截了!"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postHandle(ChannelHandlerContext context,
|
public void postHandle(ChannelHandlerContext context,
|
||||||
WeixinRequest request, WeixinResponse response,
|
WeixinRequest request, WeixinResponse response,
|
||||||
WeixinMessage message, WeixinMessageHandler handler)
|
Object message, WeixinMessageHandler handler)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
System.err.println("preHandle返回为true,执行handler后");
|
System.err.println("preHandle返回为true,执行handler后");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void afterCompletion(ChannelHandlerContext context,
|
public void afterCompletion(ChannelHandlerContext context,
|
||||||
WeixinRequest request, WeixinMessage message,
|
WeixinRequest request, Object message,
|
||||||
WeixinMessageHandler handler, WeixinException exception)
|
WeixinMessageHandler handler, WeixinException exception)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
System.err.println("请求处理完毕");
|
System.err.println("请求处理完毕");
|
||||||
|
|||||||
@ -48,7 +48,7 @@ public class MessageHandlerExecutor {
|
|||||||
return messageHandler;
|
return messageHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean applyPreHandle(WeixinRequest request, String message)
|
public boolean applyPreHandle(WeixinRequest request, Object 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++) {
|
||||||
@ -65,7 +65,7 @@ public class MessageHandlerExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void applyPostHandle(WeixinRequest request, WeixinResponse response,
|
public void applyPostHandle(WeixinRequest request, WeixinResponse response,
|
||||||
String message) throws WeixinException {
|
Object message) throws WeixinException {
|
||||||
if (messageInterceptors == null) {
|
if (messageInterceptors == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ public class MessageHandlerExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void triggerAfterCompletion(WeixinRequest request, String message,
|
public void triggerAfterCompletion(WeixinRequest request, Object message,
|
||||||
WeixinException exception) throws WeixinException {
|
WeixinException exception) throws WeixinException {
|
||||||
if (messageInterceptors == null) {
|
if (messageInterceptors == null) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,69 +0,0 @@
|
|||||||
package com.foxinmy.weixin4j.dispatcher;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext;
|
|
||||||
import javax.xml.bind.JAXBElement;
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
import javax.xml.bind.Unmarshaller;
|
|
||||||
import javax.xml.transform.Source;
|
|
||||||
import javax.xml.transform.stream.StreamSource;
|
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
|
||||||
import com.foxinmy.weixin4j.request.WeixinMessage;
|
|
||||||
import com.foxinmy.weixin4j.util.Consts;
|
|
||||||
|
|
||||||
public abstract class WeixinMessageAdapter<M> {
|
|
||||||
/**
|
|
||||||
* 消息类集合
|
|
||||||
*/
|
|
||||||
private static final Map<Class<?>, Unmarshaller> unmarshallerMap;
|
|
||||||
|
|
||||||
static {
|
|
||||||
unmarshallerMap = new HashMap<Class<?>, Unmarshaller>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected M messageRead(String message) throws WeixinException {
|
|
||||||
try {
|
|
||||||
Class<?> clazz = resolveMessageClass();
|
|
||||||
Source source = new StreamSource(new ByteArrayInputStream(
|
|
||||||
message.getBytes(Consts.UTF_8)));
|
|
||||||
JAXBElement<?> jaxbElement = getUnmarshaller().unmarshal(source,
|
|
||||||
clazz);
|
|
||||||
return (M) jaxbElement.getValue();
|
|
||||||
} catch (JAXBException e) {
|
|
||||||
throw new WeixinException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Unmarshaller getUnmarshaller() throws WeixinException {
|
|
||||||
Class<?> mineClass = resolveMessageClass();
|
|
||||||
Unmarshaller unmarshaller = unmarshallerMap.get(mineClass);
|
|
||||||
if (unmarshaller == null) {
|
|
||||||
try {
|
|
||||||
JAXBContext jaxbContext = JAXBContext.newInstance(mineClass);
|
|
||||||
unmarshaller = jaxbContext.createUnmarshaller();
|
|
||||||
unmarshallerMap.put(mineClass, unmarshaller);
|
|
||||||
} catch (JAXBException e) {
|
|
||||||
throw new WeixinException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return unmarshaller;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Class<?> resolveMessageClass() {
|
|
||||||
Class<?> clazz = WeixinMessage.class;
|
|
||||||
Type type = getClass().getGenericSuperclass();
|
|
||||||
if (type instanceof ParameterizedType) {
|
|
||||||
ParameterizedType ptype = ((ParameterizedType) type);
|
|
||||||
Type[] args = ptype.getActualTypeArguments();
|
|
||||||
clazz = (Class<?>) args[0];
|
|
||||||
}
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -4,21 +4,35 @@ import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
|
|||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBContext;
|
||||||
|
import javax.xml.bind.JAXBElement;
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
import javax.xml.bind.Unmarshaller;
|
||||||
|
import javax.xml.transform.Source;
|
||||||
|
import javax.xml.transform.stream.StreamSource;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.bean.BeanFactory;
|
import com.foxinmy.weixin4j.bean.BeanFactory;
|
||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.handler.MessageHandlerAdapter;
|
||||||
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.WeixinRequest;
|
import com.foxinmy.weixin4j.request.WeixinRequest;
|
||||||
import com.foxinmy.weixin4j.response.WeixinResponse;
|
import com.foxinmy.weixin4j.response.WeixinResponse;
|
||||||
import com.foxinmy.weixin4j.util.ClassUtil;
|
import com.foxinmy.weixin4j.util.ClassUtil;
|
||||||
|
import com.foxinmy.weixin4j.util.Consts;
|
||||||
import com.foxinmy.weixin4j.util.HttpUtil;
|
import com.foxinmy.weixin4j.util.HttpUtil;
|
||||||
import com.foxinmy.weixin4j.util.ReflectionUtil;
|
import com.foxinmy.weixin4j.util.ReflectionUtil;
|
||||||
|
|
||||||
@ -60,14 +74,30 @@ public class WeixinMessageDispatcher {
|
|||||||
*/
|
*/
|
||||||
private BeanFactory beanFactory;
|
private BeanFactory beanFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息匹配
|
||||||
|
*/
|
||||||
|
private WeixinMessageMatcher messageMatcher;
|
||||||
|
/**
|
||||||
|
* 消息转换
|
||||||
|
*/
|
||||||
|
private Map<Class<?>, Unmarshaller> messageUnmarshaller;
|
||||||
|
|
||||||
public WeixinMessageDispatcher() {
|
public WeixinMessageDispatcher() {
|
||||||
|
messageMatcher = new WeixinMessageMatcher();
|
||||||
|
messageUnmarshaller = new HashMap<Class<?>, Unmarshaller>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doDispatch(final ChannelHandlerContext context,
|
public void doDispatch(final ChannelHandlerContext context,
|
||||||
final WeixinRequest request, final String message)
|
final WeixinRequest request, final String uniqueKey)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
|
Class<?> targetClass = messageMatcher.find(uniqueKey);
|
||||||
|
Object message = request.getOriginalContent();
|
||||||
|
if (targetClass != null) {
|
||||||
|
message = messageRead(request.getOriginalContent(), targetClass);
|
||||||
|
}
|
||||||
MessageHandlerExecutor handlerExecutor = getHandlerExecutor(context,
|
MessageHandlerExecutor handlerExecutor = getHandlerExecutor(context,
|
||||||
request, message);
|
request, uniqueKey, message);
|
||||||
if (handlerExecutor == null
|
if (handlerExecutor == null
|
||||||
|| handlerExecutor.getMessageHandler() == null) {
|
|| handlerExecutor.getMessageHandler() == null) {
|
||||||
noHandlerFound(context, request, message);
|
noHandlerFound(context, request, message);
|
||||||
@ -93,23 +123,41 @@ public class WeixinMessageDispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void noHandlerFound(ChannelHandlerContext ctx,
|
protected void noHandlerFound(ChannelHandlerContext ctx,
|
||||||
WeixinRequest request, String message) {
|
WeixinRequest request, Object message) {
|
||||||
ctx.writeAndFlush(HttpUtil.createHttpResponse(null, NOT_FOUND, null))
|
ctx.writeAndFlush(HttpUtil.createHttpResponse(null, NOT_FOUND, null))
|
||||||
.addListener(ChannelFutureListener.CLOSE);
|
.addListener(ChannelFutureListener.CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MessageHandlerExecutor getHandlerExecutor(
|
protected MessageHandlerExecutor getHandlerExecutor(
|
||||||
ChannelHandlerContext context, WeixinRequest request, String message)
|
ChannelHandlerContext context, WeixinRequest request,
|
||||||
throws WeixinException {
|
String uniqueKey, Object message) throws WeixinException {
|
||||||
WeixinMessageHandler messageHandler = null;
|
WeixinMessageHandler messageHandler = null;
|
||||||
WeixinMessageHandler[] messageHandlers = getMessageHandlers();
|
WeixinMessageHandler[] messageHandlers = getMessageHandlers();
|
||||||
if (messageHandlers == null) {
|
if (messageHandlers == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (WeixinMessageHandler handler : messageHandlers) {
|
for (WeixinMessageHandler handler : messageHandlers) {
|
||||||
if (handler.canHandle(request, message)) {
|
if (handler instanceof MessageHandlerAdapter) {
|
||||||
messageHandler = handler;
|
Class<?> genericType = genericTypeRead(handler);
|
||||||
break;
|
if (!messageMatcher.match(genericType)) {
|
||||||
|
message = messageRead(request.getOriginalContent(),
|
||||||
|
genericType);
|
||||||
|
messageMatcher.regist(uniqueKey, genericType);
|
||||||
|
}
|
||||||
|
if (genericType == message.getClass()
|
||||||
|
&& handler.canHandle(request, message)) {
|
||||||
|
messageHandler = handler;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (messageHandler == null) {
|
||||||
|
for (WeixinMessageHandler handler : messageHandlers) {
|
||||||
|
if (!(handler instanceof MessageHandlerAdapter)
|
||||||
|
&& handler.canHandle(request, message)) {
|
||||||
|
messageHandler = handler;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new MessageHandlerExecutor(context, messageHandler,
|
return new MessageHandlerExecutor(context, messageHandler,
|
||||||
@ -205,6 +253,45 @@ public class WeixinMessageDispatcher {
|
|||||||
return this.messageInterceptors;
|
return this.messageInterceptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Object messageRead(String message, Class<?> clazz)
|
||||||
|
throws WeixinException {
|
||||||
|
try {
|
||||||
|
Source source = new StreamSource(new ByteArrayInputStream(
|
||||||
|
message.getBytes(Consts.UTF_8)));
|
||||||
|
JAXBElement<?> jaxbElement = getUnmarshaller(clazz).unmarshal(
|
||||||
|
source, clazz);
|
||||||
|
return jaxbElement.getValue();
|
||||||
|
} catch (JAXBException e) {
|
||||||
|
throw new WeixinException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Unmarshaller getUnmarshaller(Class<?> clazz)
|
||||||
|
throws WeixinException {
|
||||||
|
Unmarshaller unmarshaller = messageUnmarshaller.get(clazz);
|
||||||
|
if (unmarshaller == null) {
|
||||||
|
try {
|
||||||
|
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
|
||||||
|
unmarshaller = jaxbContext.createUnmarshaller();
|
||||||
|
messageUnmarshaller.put(clazz, unmarshaller);
|
||||||
|
} catch (JAXBException e) {
|
||||||
|
throw new WeixinException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unmarshaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Class<?> genericTypeRead(Object object) {
|
||||||
|
Class<?> clazz = null;
|
||||||
|
Type type = object.getClass().getGenericSuperclass();
|
||||||
|
if (type instanceof ParameterizedType) {
|
||||||
|
ParameterizedType ptype = ((ParameterizedType) type);
|
||||||
|
Type[] args = ptype.getActualTypeArguments();
|
||||||
|
clazz = (Class<?>) args[0];
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
public void setMessageHandlerList(
|
public void setMessageHandlerList(
|
||||||
List<WeixinMessageHandler> messageHandlerList) {
|
List<WeixinMessageHandler> messageHandlerList) {
|
||||||
this.messageHandlerList = messageHandlerList;
|
this.messageHandlerList = messageHandlerList;
|
||||||
|
|||||||
@ -0,0 +1,177 @@
|
|||||||
|
package com.foxinmy.weixin4j.dispatcher;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.message.ImageMessage;
|
||||||
|
import com.foxinmy.weixin4j.message.LocationMessage;
|
||||||
|
import com.foxinmy.weixin4j.message.TextMessage;
|
||||||
|
import com.foxinmy.weixin4j.message.VideoMessage;
|
||||||
|
import com.foxinmy.weixin4j.message.VoiceMessage;
|
||||||
|
import com.foxinmy.weixin4j.message.event.LocationEventMessage;
|
||||||
|
import com.foxinmy.weixin4j.mp.event.KfCloseEventMessage;
|
||||||
|
import com.foxinmy.weixin4j.mp.event.KfCreateEventMessage;
|
||||||
|
import com.foxinmy.weixin4j.mp.event.KfSwitchEventMessage;
|
||||||
|
import com.foxinmy.weixin4j.mp.event.MassEventMessage;
|
||||||
|
import com.foxinmy.weixin4j.mp.event.ScanEventMessage;
|
||||||
|
import com.foxinmy.weixin4j.mp.event.TemplatesendjobfinishMessage;
|
||||||
|
import com.foxinmy.weixin4j.qy.event.BatchjobresultMessage;
|
||||||
|
import com.foxinmy.weixin4j.qy.event.EnterAgentEventMessage;
|
||||||
|
import com.foxinmy.weixin4j.type.EventType;
|
||||||
|
import com.foxinmy.weixin4j.type.MessageType;
|
||||||
|
|
||||||
|
public class WeixinMessageMatcher {
|
||||||
|
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private final String MP_TAG = "mp";
|
||||||
|
private final String QY_TAG = "qy";
|
||||||
|
|
||||||
|
private final Map<String, Class<?>> key2ClassMap;
|
||||||
|
private final Map<Class<?>, String> class2KeyMap;
|
||||||
|
|
||||||
|
public WeixinMessageMatcher() {
|
||||||
|
key2ClassMap = new HashMap<String, Class<?>>();
|
||||||
|
class2KeyMap = new HashMap<Class<?>, String>();
|
||||||
|
init0();
|
||||||
|
init1();
|
||||||
|
init2();
|
||||||
|
init3();
|
||||||
|
log.info("detected message for events: {}", key2ClassMap.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init0() {
|
||||||
|
// /////////////////////////////////////////////////
|
||||||
|
/******************** 普通消息 ********************/
|
||||||
|
// /////////////////////////////////////////////////
|
||||||
|
String uniqueKey = MessageType.text.name();
|
||||||
|
Class<?> clazz = TextMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
uniqueKey = MessageType.image.name();
|
||||||
|
clazz = ImageMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
uniqueKey = MessageType.voice.name();
|
||||||
|
clazz = VoiceMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
uniqueKey = MessageType.video.name();
|
||||||
|
clazz = VideoMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
uniqueKey = MessageType.shortvideo.name();
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
uniqueKey = MessageType.location.name();
|
||||||
|
clazz = LocationMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init1() {
|
||||||
|
// /////////////////////////////////////////////////
|
||||||
|
/******************** 事件消息 ********************/
|
||||||
|
// /////////////////////////////////////////////////
|
||||||
|
String uniqueKey;
|
||||||
|
Class<?> clazz;
|
||||||
|
for (EventType eventType : new EventType[] { EventType.subscribe,
|
||||||
|
EventType.unsubscribe }) {
|
||||||
|
uniqueKey = String.format("%s:%s", MessageType.event.name(),
|
||||||
|
eventType.name());
|
||||||
|
clazz = com.foxinmy.weixin4j.mp.event.ScribeEventMessage.class;
|
||||||
|
regist(String.format("%s:%s", MP_TAG, uniqueKey), clazz);
|
||||||
|
}
|
||||||
|
for (EventType eventType : new EventType[] { EventType.subscribe,
|
||||||
|
EventType.unsubscribe }) {
|
||||||
|
uniqueKey = String.format("%s:%s", MessageType.event.name(),
|
||||||
|
eventType.name());
|
||||||
|
clazz = com.foxinmy.weixin4j.qy.event.ScribeEventMessage.class;
|
||||||
|
regist(String.format("%s:%s", QY_TAG, uniqueKey), clazz);
|
||||||
|
}
|
||||||
|
uniqueKey = String.format("%s:%s", MessageType.event.name(),
|
||||||
|
EventType.location.name());
|
||||||
|
clazz = LocationEventMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
for (EventType eventType : new EventType[] { EventType.click,
|
||||||
|
EventType.view }) {
|
||||||
|
uniqueKey = String.format("%s:%s", MessageType.event.name(),
|
||||||
|
eventType.name());
|
||||||
|
clazz = com.foxinmy.weixin4j.message.event.MenuEventMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
}
|
||||||
|
for (EventType eventType : new EventType[] { EventType.scancode_push,
|
||||||
|
EventType.scancode_waitmsg }) {
|
||||||
|
uniqueKey = String.format("%s:%s", MessageType.event.name(),
|
||||||
|
eventType.name());
|
||||||
|
clazz = com.foxinmy.weixin4j.message.event.MenuScanEventMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
}
|
||||||
|
for (EventType eventType : new EventType[] { EventType.pic_sysphoto,
|
||||||
|
EventType.pic_photo_or_album, EventType.pic_weixin }) {
|
||||||
|
uniqueKey = String.format("%s:%s", MessageType.event.name(),
|
||||||
|
eventType.name());
|
||||||
|
clazz = com.foxinmy.weixin4j.message.event.MenuPhotoEventMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
}
|
||||||
|
uniqueKey = String.format("%s:%s", MessageType.event.name(),
|
||||||
|
EventType.location_select.name());
|
||||||
|
clazz = com.foxinmy.weixin4j.message.event.MenuLocationEventMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init2() {
|
||||||
|
// /////////////////////////////////////////////////
|
||||||
|
/******************** 公众平台事件消息 ********************/
|
||||||
|
// /////////////////////////////////////////////////
|
||||||
|
String uniqueKey = String.format("%s:%s:%s", MP_TAG,
|
||||||
|
MessageType.event.name(), EventType.scan.name());
|
||||||
|
Class<?> clazz = ScanEventMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
uniqueKey = String.format("%s:%s:%s", MP_TAG, MessageType.event.name(),
|
||||||
|
EventType.masssendjobfinish.name());
|
||||||
|
clazz = MassEventMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
uniqueKey = String.format("%s:%s:%s", MP_TAG, MessageType.event.name(),
|
||||||
|
EventType.templatesendjobfinish.name());
|
||||||
|
clazz = TemplatesendjobfinishMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
uniqueKey = String.format("%s:%s:%s", MP_TAG, MessageType.event.name(),
|
||||||
|
EventType.kf_create_session.name());
|
||||||
|
clazz = KfCreateEventMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
uniqueKey = String.format("%s:%s:%s", MP_TAG, MessageType.event.name(),
|
||||||
|
EventType.kf_close_session.name());
|
||||||
|
clazz = KfCloseEventMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
uniqueKey = String.format("%s:%s:%s", MP_TAG, MessageType.event.name(),
|
||||||
|
EventType.kf_switch_session.name());
|
||||||
|
clazz = KfSwitchEventMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init3() {
|
||||||
|
// /////////////////////////////////////////////////
|
||||||
|
/******************** 企业号事件消息 ********************/
|
||||||
|
// /////////////////////////////////////////////////
|
||||||
|
String uniqueKey = String.format("%s:%s:%s", QY_TAG,
|
||||||
|
MessageType.event.name(), EventType.batch_job_result.name());
|
||||||
|
Class<?> clazz = BatchjobresultMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
uniqueKey = String.format("%s:%s:%s", QY_TAG, MessageType.event.name(),
|
||||||
|
EventType.enter_agent.name());
|
||||||
|
clazz = EnterAgentEventMessage.class;
|
||||||
|
regist(uniqueKey, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void regist(String uniqueKey, Class<?> clazz) {
|
||||||
|
key2ClassMap.put(uniqueKey, clazz);
|
||||||
|
class2KeyMap.put(clazz, uniqueKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean match(Object keyOrClass) {
|
||||||
|
return key2ClassMap.containsKey(keyOrClass)
|
||||||
|
|| class2KeyMap.containsKey(keyOrClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<?> find(String uniqueKey) {
|
||||||
|
return key2ClassMap.get(uniqueKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,13 +14,13 @@ public class BlankMessageHandler implements WeixinMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canHandle(WeixinRequest request, String message)
|
public boolean canHandle(WeixinRequest request, Object message)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WeixinResponse doHandle(WeixinRequest request, String message)
|
public WeixinResponse doHandle(WeixinRequest request, Object message)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
return BlankResponse.global;
|
return BlankResponse.global;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,14 +14,14 @@ public class DebugMessageHandler implements WeixinMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canHandle(WeixinRequest request, String message)
|
public boolean canHandle(WeixinRequest request, Object message)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WeixinResponse doHandle(WeixinRequest request, String message)
|
public WeixinResponse doHandle(WeixinRequest request, Object message)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
return new TextResponse(message);
|
return new TextResponse(message.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,32 +1,30 @@
|
|||||||
package com.foxinmy.weixin4j.handler;
|
package com.foxinmy.weixin4j.handler;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.dispatcher.WeixinMessageAdapter;
|
|
||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
import com.foxinmy.weixin4j.request.WeixinRequest;
|
import com.foxinmy.weixin4j.request.WeixinRequest;
|
||||||
import com.foxinmy.weixin4j.response.WeixinResponse;
|
import com.foxinmy.weixin4j.response.WeixinResponse;
|
||||||
|
|
||||||
public abstract class MessageHandlerAdapter<M> extends WeixinMessageAdapter<M>
|
@SuppressWarnings("unchecked")
|
||||||
implements WeixinMessageHandler {
|
public abstract class MessageHandlerAdapter<M> implements WeixinMessageHandler {
|
||||||
|
|
||||||
private M message;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canHandle(WeixinRequest request, String message)
|
public boolean canHandle(WeixinRequest request, Object message)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
this.message = super.messageRead(message);
|
return canHandle0(request, (M) message);
|
||||||
return canHandle0(request, message, this.message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean canHandle0(WeixinRequest request, String message,
|
public boolean canHandle0(WeixinRequest request, M message)
|
||||||
M m) throws WeixinException;
|
throws WeixinException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WeixinResponse doHandle(WeixinRequest request, String message)
|
public WeixinResponse doHandle(WeixinRequest request, Object message)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
return doHandle0(request, message, this.message);
|
return doHandle0(request, (M) message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract WeixinResponse doHandle0(WeixinRequest request,
|
public abstract WeixinResponse doHandle0(WeixinRequest request, M message)
|
||||||
String message, M m) throws WeixinException;
|
throws WeixinException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ public interface WeixinMessageHandler {
|
|||||||
* 微信消息
|
* 微信消息
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean canHandle(WeixinRequest request, String message)
|
public boolean canHandle(WeixinRequest request, Object message)
|
||||||
throws WeixinException;
|
throws WeixinException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,6 +36,6 @@ public interface WeixinMessageHandler {
|
|||||||
* 微信消息
|
* 微信消息
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public WeixinResponse doHandle(WeixinRequest request, String message)
|
public WeixinResponse doHandle(WeixinRequest request, Object message)
|
||||||
throws WeixinException;
|
throws WeixinException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@ package com.foxinmy.weixin4j.interceptor;
|
|||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.dispatcher.WeixinMessageAdapter;
|
|
||||||
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.WeixinRequest;
|
import com.foxinmy.weixin4j.request.WeixinRequest;
|
||||||
@ -17,45 +16,26 @@ import com.foxinmy.weixin4j.response.WeixinResponse;
|
|||||||
* @since JDK 1.7
|
* @since JDK 1.7
|
||||||
* @see
|
* @see
|
||||||
*/
|
*/
|
||||||
public abstract class MessageInterceptorAdapter<M> extends
|
public abstract class MessageInterceptorAdapter implements
|
||||||
WeixinMessageAdapter<M> implements WeixinMessageInterceptor {
|
WeixinMessageInterceptor {
|
||||||
|
|
||||||
private M message;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean preHandle(ChannelHandlerContext context,
|
public boolean preHandle(ChannelHandlerContext context,
|
||||||
WeixinRequest request, final String message,
|
WeixinRequest request, Object message, WeixinMessageHandler handler)
|
||||||
WeixinMessageHandler handler) throws WeixinException {
|
throws WeixinException {
|
||||||
this.message = super.messageRead(message);
|
return true;
|
||||||
return preHandle0(context, request, this.message, handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean preHandle0(ChannelHandlerContext context,
|
|
||||||
WeixinRequest request, M message, WeixinMessageHandler handler)
|
|
||||||
throws WeixinException;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postHandle(ChannelHandlerContext context,
|
public void postHandle(ChannelHandlerContext context,
|
||||||
WeixinRequest request, WeixinResponse response, String message,
|
WeixinRequest request, WeixinResponse response, Object message,
|
||||||
WeixinMessageHandler handler) throws WeixinException {
|
WeixinMessageHandler handler) throws WeixinException {
|
||||||
postHandle0(context, request, response, message, this.message, handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void postHandle0(ChannelHandlerContext context,
|
|
||||||
WeixinRequest request, WeixinResponse response, String message,
|
|
||||||
M m, WeixinMessageHandler handler) throws WeixinException;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterCompletion(ChannelHandlerContext context,
|
public void afterCompletion(ChannelHandlerContext context,
|
||||||
WeixinRequest request, String message,
|
WeixinRequest request, Object message,
|
||||||
WeixinMessageHandler handler, WeixinException exception)
|
WeixinMessageHandler handler, WeixinException exception)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
afterCompletion0(context, request, message, this.message, handler,
|
|
||||||
exception);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void afterCompletion0(ChannelHandlerContext context,
|
|
||||||
WeixinRequest request, String message, M m,
|
|
||||||
WeixinMessageHandler handler, WeixinException exception)
|
|
||||||
throws WeixinException;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,7 +33,7 @@ public interface WeixinMessageInterceptor {
|
|||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
boolean preHandle(ChannelHandlerContext context, WeixinRequest request,
|
boolean preHandle(ChannelHandlerContext context, WeixinRequest request,
|
||||||
String message, WeixinMessageHandler handler)
|
Object message, WeixinMessageHandler handler)
|
||||||
throws WeixinException;
|
throws WeixinException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,7 +52,7 @@ public interface WeixinMessageInterceptor {
|
|||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
void postHandle(ChannelHandlerContext context, WeixinRequest request,
|
void postHandle(ChannelHandlerContext context, WeixinRequest request,
|
||||||
WeixinResponse response, String message,
|
WeixinResponse response, Object message,
|
||||||
WeixinMessageHandler handler) throws WeixinException;
|
WeixinMessageHandler handler) throws WeixinException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,6 +71,6 @@ public interface WeixinMessageInterceptor {
|
|||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
void afterCompletion(ChannelHandlerContext context, WeixinRequest request,
|
void afterCompletion(ChannelHandlerContext context, WeixinRequest request,
|
||||||
String message, WeixinMessageHandler handler,
|
Object message, WeixinMessageHandler handler,
|
||||||
WeixinException exception) throws WeixinException;
|
WeixinException exception) throws WeixinException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,28 +8,19 @@ import io.netty.channel.ChannelHandlerContext;
|
|||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import io.netty.handler.codec.http.HttpMethod;
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext;
|
|
||||||
import javax.xml.bind.JAXBElement;
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
import javax.xml.bind.Unmarshaller;
|
|
||||||
import javax.xml.transform.Source;
|
|
||||||
import javax.xml.transform.stream.StreamSource;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.bean.AesToken;
|
import com.foxinmy.weixin4j.bean.AesToken;
|
||||||
import com.foxinmy.weixin4j.dispatcher.WeixinMessageDispatcher;
|
import com.foxinmy.weixin4j.dispatcher.WeixinMessageDispatcher;
|
||||||
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.type.EncryptType;
|
import com.foxinmy.weixin4j.type.EncryptType;
|
||||||
import com.foxinmy.weixin4j.util.Consts;
|
import com.foxinmy.weixin4j.util.Consts;
|
||||||
import com.foxinmy.weixin4j.util.HttpUtil;
|
import com.foxinmy.weixin4j.util.HttpUtil;
|
||||||
import com.foxinmy.weixin4j.util.MessageUtil;
|
import com.foxinmy.weixin4j.util.MessageUtil;
|
||||||
import com.foxinmy.weixin4j.util.StringUtil;
|
import com.foxinmy.weixin4j.util.StringUtil;
|
||||||
|
import com.foxinmy.weixin4j.xml.CruxMessageHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信请求处理类
|
* 微信请求处理类
|
||||||
@ -108,27 +99,17 @@ public class WeixinRequestHandler extends
|
|||||||
.addListener(ChannelFutureListener.CLOSE);
|
.addListener(ChannelFutureListener.CLOSE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final String message = request.getOriginalContent();
|
CruxMessageHandler messageHandler = CruxMessageHandler.parser(request
|
||||||
WeixinMessage weixinMessage;
|
.getOriginalContent());
|
||||||
try {
|
|
||||||
Unmarshaller unmarshaller = JAXBContext.newInstance(
|
|
||||||
WeixinMessage.class).createUnmarshaller();
|
|
||||||
Source source = new StreamSource(new ByteArrayInputStream(
|
|
||||||
message.getBytes()));
|
|
||||||
JAXBElement<WeixinMessage> jaxbElement = unmarshaller.unmarshal(
|
|
||||||
source, WeixinMessage.class);
|
|
||||||
weixinMessage = jaxbElement.getValue();
|
|
||||||
} catch (JAXBException e) {
|
|
||||||
throw new WeixinException(e);
|
|
||||||
}
|
|
||||||
ctx.channel().attr(Consts.ENCRYPTTYPE_KEY)
|
ctx.channel().attr(Consts.ENCRYPTTYPE_KEY)
|
||||||
.set(request.getEncryptType());
|
.set(request.getEncryptType());
|
||||||
ctx.channel().attr(Consts.USEROPENID_KEY)
|
ctx.channel().attr(Consts.USEROPENID_KEY)
|
||||||
.set(weixinMessage.getFromUserName());
|
.set(messageHandler.getFromUserName());
|
||||||
if (StringUtil.isBlank(aesToken.getAppid())) {
|
if (StringUtil.isBlank(aesToken.getAppid())) {
|
||||||
ctx.channel().attr(Consts.ACCOUNTOPENID_KEY)
|
ctx.channel().attr(Consts.ACCOUNTOPENID_KEY)
|
||||||
.set(weixinMessage.getToUserName());
|
.set(messageHandler.getToUserName());
|
||||||
}
|
}
|
||||||
messageDispatcher.doDispatch(ctx, request, message);
|
messageDispatcher.doDispatch(ctx, request,
|
||||||
|
messageHandler.getUniqueKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,57 +26,56 @@ public enum EventType {
|
|||||||
* @see com.foxinmy.weixin4j.message.event.LocationEventMessage
|
* @see com.foxinmy.weixin4j.message.event.LocationEventMessage
|
||||||
*/
|
*/
|
||||||
location,
|
location,
|
||||||
/**
|
|
||||||
* 菜单扫描事件
|
|
||||||
*
|
|
||||||
* @see com.foxinmy.weixin4j.message.event.menu.MenuScanEventMessage
|
|
||||||
*/
|
|
||||||
scancode_push,
|
|
||||||
/**
|
/**
|
||||||
* 菜单点击关键字事件
|
* 菜单点击关键字事件
|
||||||
*
|
*
|
||||||
* @see com.foxinmy.weixin4j.message.event.menu.MenuEventMessage
|
* @see com.foxinmy.weixin4j.message.event.MenuEventMessage
|
||||||
*/
|
*/
|
||||||
view,
|
view,
|
||||||
/**
|
/**
|
||||||
* 菜单点击链接事件
|
* 菜单点击链接事件
|
||||||
*
|
*
|
||||||
* @see com.foxinmy.weixin4j.message.event.menu.MenuEventMessage
|
* @see com.foxinmy.weixin4j.message.event.MenuEventMessage
|
||||||
*/
|
*/
|
||||||
click,
|
click,
|
||||||
|
/**
|
||||||
|
* 菜单扫描事件
|
||||||
|
*
|
||||||
|
* @see com.foxinmy.weixin4j.message.event.MenuScanEventMessage
|
||||||
|
*/
|
||||||
|
scancode_push,
|
||||||
/**
|
/**
|
||||||
* 菜单扫描并调出等待界面事件
|
* 菜单扫描并调出等待界面事件
|
||||||
*
|
*
|
||||||
* @see com.foxinmy.weixin4j.message.event.menu.MenuScanEventMessage
|
* @see com.foxinmy.weixin4j.message.event.MenuScanEventMessage
|
||||||
*/
|
*/
|
||||||
scancode_waitmsg,
|
scancode_waitmsg,
|
||||||
/**
|
/**
|
||||||
* 菜单弹出拍照事件
|
* 菜单弹出拍照事件
|
||||||
*
|
*
|
||||||
* @see com.foxinmy.weixin4j.message.event.menu.MenuPhotoEventMessage
|
* @see com.foxinmy.weixin4j.message.event.MenuPhotoEventMessage
|
||||||
*/
|
*/
|
||||||
pic_sysphoto,
|
pic_sysphoto,
|
||||||
/**
|
/**
|
||||||
* 菜单弹出发图事件
|
* 菜单弹出发图事件
|
||||||
*
|
*
|
||||||
* @see com.foxinmy.weixin4j.message.event.menu.MenuPhotoEventMessage
|
* @see com.foxinmy.weixin4j.message.event.MenuPhotoEventMessage
|
||||||
*/
|
*/
|
||||||
pic_photo_or_album,
|
pic_photo_or_album,
|
||||||
/**
|
/**
|
||||||
* 菜单弹出发图事件
|
* 菜单弹出发图事件
|
||||||
*
|
*
|
||||||
* @see com.foxinmy.weixin4j.message.event.menu.MenuPhotoEventMessage
|
* @see com.foxinmy.weixin4j.message.event.MenuPhotoEventMessage
|
||||||
*/
|
*/
|
||||||
pic_weixin,
|
pic_weixin,
|
||||||
/**
|
/**
|
||||||
* 菜单发送地理位置事件
|
* 菜单发送地理位置事件
|
||||||
*
|
*
|
||||||
* @see com.foxinmy.weixin4j.message.event.menu.MenuLocationEventMessage
|
* @see com.foxinmy.weixin4j.message.event.MenuLocationEventMessage
|
||||||
*/
|
*/
|
||||||
location_select,
|
location_select,
|
||||||
|
|
||||||
// ------------------------------公众平台特有------------------------------
|
// ------------------------------公众平台特有------------------------------
|
||||||
//
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 二维码扫描事件
|
* 二维码扫描事件
|
||||||
@ -114,6 +113,8 @@ public enum EventType {
|
|||||||
* @see com.foxinmy.weixin4j.mp.event.KfSwitchEventMessage
|
* @see com.foxinmy.weixin4j.mp.event.KfSwitchEventMessage
|
||||||
*/
|
*/
|
||||||
kf_switch_session,
|
kf_switch_session,
|
||||||
|
|
||||||
|
// ------------------------------企业号特有------------------------------
|
||||||
/**
|
/**
|
||||||
* 异步任务完成事件
|
* 异步任务完成事件
|
||||||
*
|
*
|
||||||
|
|||||||
@ -52,8 +52,7 @@ public final class ClassUtil {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new UnsupportedOperationException(String.format(
|
return null;
|
||||||
"unknow protocol:", protocol));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,95 @@
|
|||||||
|
package com.foxinmy.weixin4j.xml;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.XMLReader;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
import org.xml.sax.helpers.XMLReaderFactory;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.type.MessageType;
|
||||||
|
import com.foxinmy.weixin4j.util.Consts;
|
||||||
|
import com.foxinmy.weixin4j.util.StringUtil;
|
||||||
|
|
||||||
|
public class CruxMessageHandler extends DefaultHandler {
|
||||||
|
|
||||||
|
private String fromUserName;
|
||||||
|
private String toUserName;
|
||||||
|
private String msgType;
|
||||||
|
private String eventType;
|
||||||
|
private String agentId;
|
||||||
|
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startDocument() throws SAXException {
|
||||||
|
fromUserName = null;
|
||||||
|
toUserName = null;
|
||||||
|
msgType = null;
|
||||||
|
eventType = null;
|
||||||
|
agentId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName)
|
||||||
|
throws SAXException {
|
||||||
|
if (localName.equalsIgnoreCase("fromUserName")) {
|
||||||
|
fromUserName = content;
|
||||||
|
} else if (localName.equalsIgnoreCase("toUserName")) {
|
||||||
|
toUserName = content;
|
||||||
|
} else if (localName.equalsIgnoreCase("msgType")) {
|
||||||
|
msgType = content.toLowerCase();
|
||||||
|
} else if (localName.equalsIgnoreCase("event")) {
|
||||||
|
eventType = content.toLowerCase();
|
||||||
|
} else if (localName.equalsIgnoreCase("agentId")) {
|
||||||
|
agentId = content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void characters(char[] ch, int start, int length)
|
||||||
|
throws SAXException {
|
||||||
|
this.content = new String(ch, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUniqueKey() {
|
||||||
|
StringBuilder uniqueKey = new StringBuilder();
|
||||||
|
uniqueKey.append(msgType);
|
||||||
|
if (msgType.equals(MessageType.event.name())) {
|
||||||
|
if (StringUtil.isBlank(agentId)) {
|
||||||
|
uniqueKey.insert(0, "mp:");
|
||||||
|
} else {
|
||||||
|
uniqueKey.insert(0, "qy:");
|
||||||
|
}
|
||||||
|
uniqueKey.append(":").append(eventType);
|
||||||
|
}
|
||||||
|
return uniqueKey.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFromUserName() {
|
||||||
|
return fromUserName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToUserName() {
|
||||||
|
return toUserName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CruxMessageHandler global = new CruxMessageHandler();
|
||||||
|
|
||||||
|
public static CruxMessageHandler parser(String xmlContent)
|
||||||
|
throws RuntimeException {
|
||||||
|
try {
|
||||||
|
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
|
||||||
|
xmlReader.setContentHandler(global);
|
||||||
|
xmlReader.parse(new InputSource(new ByteArrayInputStream(xmlContent
|
||||||
|
.getBytes(Consts.UTF_8))));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (SAXException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return global;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@ import com.foxinmy.weixin4j.util.Consts;
|
|||||||
public class EncryptMessageHandler extends DefaultHandler {
|
public class EncryptMessageHandler extends DefaultHandler {
|
||||||
|
|
||||||
private String encryptContent;
|
private String encryptContent;
|
||||||
|
private String content;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startDocument() throws SAXException {
|
public void startDocument() throws SAXException {
|
||||||
@ -24,28 +25,30 @@ public class EncryptMessageHandler extends DefaultHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void startElement(String uri, String localName, String qName,
|
public void startElement(String uri, String localName, String qName,
|
||||||
Attributes attributes) throws SAXException {
|
Attributes attributes) throws SAXException {
|
||||||
if (qName.equalsIgnoreCase("encrypt")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endElement(String uri, String localName, String qName)
|
public void endElement(String uri, String localName, String qName)
|
||||||
throws SAXException {
|
throws SAXException {
|
||||||
|
if (localName.equalsIgnoreCase("encrypt")) {
|
||||||
|
encryptContent = content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void characters(char[] ch, int start, int length)
|
public void characters(char[] ch, int start, int length)
|
||||||
throws SAXException {
|
throws SAXException {
|
||||||
this.encryptContent = new String(ch, start, length);
|
this.content = new String(ch, start, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEncryptContent() {
|
public String getEncryptContent() {
|
||||||
return encryptContent;
|
return encryptContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final static EncryptMessageHandler messageHandler = new EncryptMessageHandler();
|
||||||
|
|
||||||
public static String parser(String xmlContent) throws RuntimeException {
|
public static String parser(String xmlContent) throws RuntimeException {
|
||||||
EncryptMessageHandler messageHandler = new EncryptMessageHandler();
|
|
||||||
try {
|
try {
|
||||||
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
|
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
|
||||||
xmlReader.setContentHandler(messageHandler);
|
xmlReader.setContentHandler(messageHandler);
|
||||||
|
|||||||
@ -57,17 +57,11 @@ public class MessageServerStartup {
|
|||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
public void test3() throws WeixinException {
|
public void test3() throws WeixinException {
|
||||||
// 文本消息回复
|
// 针对文本消息回复
|
||||||
WeixinMessageHandler messageHandler = new MessageHandlerAdapter<TextMessage>() {
|
WeixinMessageHandler messageHandler = new MessageHandlerAdapter<TextMessage>() {
|
||||||
@Override
|
|
||||||
public boolean canHandle0(WeixinRequest request, String message,
|
|
||||||
TextMessage m) throws WeixinException {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WeixinResponse doHandle0(WeixinRequest request,
|
public WeixinResponse doHandle0(WeixinRequest request,
|
||||||
String message, TextMessage m) throws WeixinException {
|
TextMessage message) throws WeixinException {
|
||||||
return new TextResponse("HelloWorld!");
|
return new TextResponse("HelloWorld!");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -88,7 +82,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, String message,
|
WeixinRequest request, Object message,
|
||||||
WeixinMessageHandler handler) throws WeixinException {
|
WeixinMessageHandler handler) throws WeixinException {
|
||||||
context.writeAndFlush(new TextResponse("所有消息被拦截了!"));
|
context.writeAndFlush(new TextResponse("所有消息被拦截了!"));
|
||||||
return false;
|
return false;
|
||||||
@ -97,14 +91,14 @@ public class MessageServerStartup {
|
|||||||
@Override
|
@Override
|
||||||
public void postHandle(ChannelHandlerContext context,
|
public void postHandle(ChannelHandlerContext context,
|
||||||
WeixinRequest request, WeixinResponse response,
|
WeixinRequest request, WeixinResponse response,
|
||||||
String message, WeixinMessageHandler handler)
|
Object message, WeixinMessageHandler handler)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
System.err.println("preHandle返回为true,执行handler后");
|
System.err.println("preHandle返回为true,执行handler后");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterCompletion(ChannelHandlerContext context,
|
public void afterCompletion(ChannelHandlerContext context,
|
||||||
WeixinRequest request, String message,
|
WeixinRequest request, Object message,
|
||||||
WeixinMessageHandler handler, WeixinException exception)
|
WeixinMessageHandler handler, WeixinException exception)
|
||||||
throws WeixinException {
|
throws WeixinException {
|
||||||
System.err.println("请求处理完毕");
|
System.err.println("请求处理完毕");
|
||||||
@ -115,6 +109,6 @@ public class MessageServerStartup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws WeixinException {
|
public static void main(String[] args) throws WeixinException {
|
||||||
new MessageServerStartup().test1();
|
new MessageServerStartup().test5();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user