weixin4j-server: WeixinServerBootstrap 构造函数支持多个公众号 &

MessageHandlerAdapter 声明时限定泛型为 WeixinMessage 的子类
This commit is contained in:
jinyu 2015-07-31 09:05:08 +08:00
parent 357952e70e
commit ea03c92eb0
8 changed files with 68 additions and 29 deletions

View File

@ -394,4 +394,9 @@
* 2015-07-30 * 2015-07-30
+ **weixin4j-qy**: 调整[WeixinSuiteProxy](./weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinSuiteProxy.java)对多个套件的支持 + **weixin4j-qy**: 调整[WeixinSuiteProxy](./weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinSuiteProxy.java)对多个套件的支持
* 2015-07-31
+ **weixin4j-server**:`WeixinServerBootstrap` 构造函数支持多个公众号
+ **weixin4j-server**:`MessageHandlerAdapter` 声明时限定泛型为`WeixinMessage`的子类

View File

@ -56,4 +56,10 @@
* 2015-07-04 * 2015-07-04
+ released 1.0.3 + released 1.0.3
* 2015-07-31
`WeixinServerBootstrap` 构造函数支持多个公众号
`MessageHandlerAdapter` 声明时限定泛型为`WeixinMessage`的子类

View File

@ -21,6 +21,7 @@ import com.foxinmy.weixin4j.mp.event.MassEventMessage;
import com.foxinmy.weixin4j.mp.event.TemplatesendjobfinishMessage; import com.foxinmy.weixin4j.mp.event.TemplatesendjobfinishMessage;
import com.foxinmy.weixin4j.qy.event.BatchjobresultMessage; import com.foxinmy.weixin4j.qy.event.BatchjobresultMessage;
import com.foxinmy.weixin4j.qy.event.EnterAgentEventMessage; import com.foxinmy.weixin4j.qy.event.EnterAgentEventMessage;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.type.AccountType; import com.foxinmy.weixin4j.type.AccountType;
import com.foxinmy.weixin4j.type.EventType; import com.foxinmy.weixin4j.type.EventType;
import com.foxinmy.weixin4j.type.MessageType; import com.foxinmy.weixin4j.type.MessageType;
@ -36,10 +37,10 @@ import com.foxinmy.weixin4j.type.MessageType;
*/ */
public class DefaultMessageMatcher implements WeixinMessageMatcher { public class DefaultMessageMatcher implements WeixinMessageMatcher {
private final Map<MessageKey, Class<?>> messageClassMap; private final Map<MessageKey, Class<? extends WeixinMessage>> messageClassMap;
public DefaultMessageMatcher() { public DefaultMessageMatcher() {
messageClassMap = new HashMap<MessageKey, Class<?>>(); messageClassMap = new HashMap<MessageKey, Class<? extends WeixinMessage>>();
initMessageClass(); initMessageClass();
} }
@ -159,12 +160,13 @@ public class DefaultMessageMatcher implements WeixinMessageMatcher {
} }
@Override @Override
public Class<?> match(MessageKey messageKey) { public Class<? extends WeixinMessage> match(MessageKey messageKey) {
return messageClassMap.get(messageKey); return messageClassMap.get(messageKey);
} }
@Override @Override
public void regist(MessageKey messageKey, Class<?> messageClass) { public void regist(MessageKey messageKey,
Class<? extends WeixinMessage> messageClass) {
Class<?> clazz = messageClassMap.get(messageKey); Class<?> clazz = messageClassMap.get(messageKey);
if (clazz != null) { if (clazz != null) {
throw new IllegalArgumentException("duplicate messagekey '" throw new IllegalArgumentException("duplicate messagekey '"

View File

@ -28,6 +28,7 @@ import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.handler.MessageHandlerAdapter; 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.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;
@ -88,7 +89,7 @@ public class WeixinMessageDispatcher {
/** /**
* 消息转换 * 消息转换
*/ */
private Map<Class<?>, Unmarshaller> messageUnmarshaller; private Map<Class<? extends WeixinMessage>, Unmarshaller> messageUnmarshaller;
/** /**
* 开启debug:未匹配到MessageHanlder输出消息信息 * 开启debug:未匹配到MessageHanlder输出消息信息
@ -101,7 +102,7 @@ public class WeixinMessageDispatcher {
public WeixinMessageDispatcher(WeixinMessageMatcher messageMatcher) { public WeixinMessageDispatcher(WeixinMessageMatcher messageMatcher) {
this.messageMatcher = messageMatcher; this.messageMatcher = messageMatcher;
this.messageUnmarshaller = new HashMap<Class<?>, Unmarshaller>(); this.messageUnmarshaller = new HashMap<Class<? extends WeixinMessage>, Unmarshaller>();
} }
/** /**
@ -120,11 +121,9 @@ public class WeixinMessageDispatcher {
throws WeixinException { throws WeixinException {
MessageKey messageKey = defineMessageKey(cruxMessage.getMsgType(), MessageKey messageKey = defineMessageKey(cruxMessage.getMsgType(),
cruxMessage.getEventType(), cruxMessage.getAccountType()); cruxMessage.getEventType(), cruxMessage.getAccountType());
Class<?> targetClass = messageMatcher.match(messageKey); Class<? extends WeixinMessage> targetClass = messageMatcher
Object message = request.getOriginalContent(); .match(messageKey);
if (targetClass != null) { Object message = messageRead(request.getOriginalContent(), targetClass);
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, cruxMessage.getNodeNames()); request, messageKey, message, cruxMessage.getNodeNames());
@ -178,7 +177,7 @@ public class WeixinMessageDispatcher {
protected void noHandlerFound(ChannelHandlerContext context, protected void noHandlerFound(ChannelHandlerContext context,
WeixinRequest request, Object message) { WeixinRequest request, Object message) {
if (isDebug) { if (isDebug) {
if (message instanceof String) { if (message == null) {
context.writeAndFlush( context.writeAndFlush(
new TextResponse(request.getOriginalContent() new TextResponse(request.getOriginalContent()
.replaceAll("\\!\\[CDATA\\[", "") .replaceAll("\\!\\[CDATA\\[", "")
@ -357,13 +356,16 @@ public class WeixinMessageDispatcher {
* @return 消息对象 * @return 消息对象
* @throws WeixinException * @throws WeixinException
*/ */
protected Object messageRead(String message, Class<?> clazz) protected Object messageRead(String message,
throws WeixinException { Class<? extends WeixinMessage> clazz) throws WeixinException {
if (clazz == null) {
return null;
}
try { try {
Source source = new StreamSource(new ByteArrayInputStream( Source source = new StreamSource(new ByteArrayInputStream(
message.getBytes(Consts.UTF_8))); message.getBytes(Consts.UTF_8)));
JAXBElement<?> jaxbElement = getUnmarshaller(clazz).unmarshal( JAXBElement<? extends WeixinMessage> jaxbElement = getUnmarshaller(
source, clazz); clazz).unmarshal(source, clazz);
return jaxbElement.getValue(); return jaxbElement.getValue();
} catch (JAXBException e) { } catch (JAXBException e) {
throw new WeixinException(e); throw new WeixinException(e);
@ -378,7 +380,7 @@ public class WeixinMessageDispatcher {
* @return 消息转换器 * @return 消息转换器
* @throws WeixinException * @throws WeixinException
*/ */
protected Unmarshaller getUnmarshaller(Class<?> clazz) protected Unmarshaller getUnmarshaller(Class<? extends WeixinMessage> clazz)
throws WeixinException { throws WeixinException {
Unmarshaller unmarshaller = messageUnmarshaller.get(clazz); Unmarshaller unmarshaller = messageUnmarshaller.get(clazz);
if (unmarshaller == null) { if (unmarshaller == null) {
@ -445,7 +447,8 @@ public class WeixinMessageDispatcher {
this.beanFactory = beanFactory; this.beanFactory = beanFactory;
} }
public void registMessageClass(MessageKey messageKey, Class<?> messageClass) { public void registMessageClass(MessageKey messageKey,
Class<? extends WeixinMessage> messageClass) {
messageMatcher.regist(messageKey, messageClass); messageMatcher.regist(messageKey, messageClass);
} }

View File

@ -1,5 +1,7 @@
package com.foxinmy.weixin4j.dispatcher; package com.foxinmy.weixin4j.dispatcher;
import com.foxinmy.weixin4j.request.WeixinMessage;
/** /**
* 微信消息匹配 * 微信消息匹配
* *
@ -17,7 +19,7 @@ public interface WeixinMessageMatcher {
* 消息key * 消息key
* @return 消息类型 * @return 消息类型
*/ */
public Class<?> match(MessageKey messageKey); public Class<? extends WeixinMessage> match(MessageKey messageKey);
/** /**
* 注册消息类型程序没有及时更新而微信又产生了新的消息类型 * 注册消息类型程序没有及时更新而微信又产生了新的消息类型
@ -27,5 +29,6 @@ public interface WeixinMessageMatcher {
* @param messageClass * @param messageClass
* 消息类型 * 消息类型
*/ */
public void regist(MessageKey messageKey, Class<?> messageClass); public void regist(MessageKey messageKey,
Class<? extends WeixinMessage> messageClass);
} }

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;
@ -16,7 +17,8 @@ import com.foxinmy.weixin4j.response.WeixinResponse;
* @see * @see
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public abstract class MessageHandlerAdapter<M> implements WeixinMessageHandler { public abstract class MessageHandlerAdapter<M extends WeixinMessage> implements
WeixinMessageHandler {
@Override @Override
public boolean canHandle(WeixinRequest request, Object message, public boolean canHandle(WeixinRequest request, Object message,

View File

@ -1,8 +1,11 @@
package com.foxinmy.weixin4j.request; package com.foxinmy.weixin4j.request;
import java.beans.Transient;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
/** /**
* 微信消息基类 * 微信消息基类
@ -90,6 +93,12 @@ public class WeixinMessage implements Serializable {
return createTime; return createTime;
} }
@Transient
@XmlTransient
public Date getFormatCreateTime() {
return createTime > 0l ? new Date(createTime * 1000l) : null;
}
public String getMsgType() { public String getMsgType() {
return msgType; return msgType;
} }

View File

@ -24,6 +24,7 @@ import com.foxinmy.weixin4j.dispatcher.WeixinMessageMatcher;
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.socket.WeixinServerInitializer; import com.foxinmy.weixin4j.socket.WeixinServerInitializer;
import com.foxinmy.weixin4j.util.AesToken; import com.foxinmy.weixin4j.util.AesToken;
@ -81,7 +82,7 @@ public final class WeixinServerBootstrap {
* 明文模式 * 明文模式
* *
* @param weixinid * @param weixinid
* 微信号(原始ID/appid/cropid) * 微信号(原始ID/appid/corpid)
* @param token * @param token
* 开发者token * 开发者token
* *
@ -94,7 +95,7 @@ public final class WeixinServerBootstrap {
* 兼容模式 & 密文模式 * 兼容模式 & 密文模式
* *
* @param appid * @param appid
* 公众号的appid * 公众号的appid/corpid
* @param token * @param token
* 开发者填写的token * 开发者填写的token
* @param aesKey * @param aesKey
@ -108,7 +109,7 @@ public final class WeixinServerBootstrap {
* 多个公众号的支持 * 多个公众号的支持
* <p> * <p>
* <font color="red">请注意需在服务接收事件的URL中附加一个名为wexin_id的参数,其值请填写公众号的appid/ * <font color="red">请注意需在服务接收事件的URL中附加一个名为wexin_id的参数,其值请填写公众号的appid/
* cropid</font> * corpid</font>
* <p> * <p>
* *
* @param aesTokens * @param aesTokens
@ -123,7 +124,7 @@ public final class WeixinServerBootstrap {
* 多个公众号的支持 * 多个公众号的支持
* <p> * <p>
* <font color="red">请注意需在服务接收事件的URL中附加一个名为wexin_id的参数,其值请填写公众号的appid/ * <font color="red">请注意需在服务接收事件的URL中附加一个名为wexin_id的参数,其值请填写公众号的appid/
* cropid</font> * corpid</font>
* <p> * <p>
* *
* @param messageMatcher * @param messageMatcher
@ -152,7 +153,15 @@ public final class WeixinServerBootstrap {
* *
*/ */
public void startup() throws WeixinException { public void startup() throws WeixinException {
startup(DEFAULT_BOSSTHREADS, DEFAULT_WORKERTHREADS, DEFAULT_SERVERPORT); startup(DEFAULT_SERVERPORT);
}
/**
* 指定端口启动服务
*
*/
public void startup(int serverPort) throws WeixinException {
startup(DEFAULT_BOSSTHREADS, DEFAULT_WORKERTHREADS, serverPort);
} }
/** /**
@ -296,7 +305,7 @@ public final class WeixinServerBootstrap {
* @return * @return
*/ */
public WeixinServerBootstrap registMessageClass(MessageKey messageKey, public WeixinServerBootstrap registMessageClass(MessageKey messageKey,
Class<?> messageClass) { Class<? extends WeixinMessage> messageClass) {
messageDispatcher.registMessageClass(messageKey, messageClass); messageDispatcher.registMessageClass(messageKey, messageClass);
return this; return this;
} }