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

@ -395,3 +395,8 @@
+ **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

@ -57,3 +57,9 @@
* 2015-07-04
+ 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.qy.event.BatchjobresultMessage;
import com.foxinmy.weixin4j.qy.event.EnterAgentEventMessage;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.type.AccountType;
import com.foxinmy.weixin4j.type.EventType;
import com.foxinmy.weixin4j.type.MessageType;
@ -36,10 +37,10 @@ import com.foxinmy.weixin4j.type.MessageType;
*/
public class DefaultMessageMatcher implements WeixinMessageMatcher {
private final Map<MessageKey, Class<?>> messageClassMap;
private final Map<MessageKey, Class<? extends WeixinMessage>> messageClassMap;
public DefaultMessageMatcher() {
messageClassMap = new HashMap<MessageKey, Class<?>>();
messageClassMap = new HashMap<MessageKey, Class<? extends WeixinMessage>>();
initMessageClass();
}
@ -159,12 +160,13 @@ public class DefaultMessageMatcher implements WeixinMessageMatcher {
}
@Override
public Class<?> match(MessageKey messageKey) {
public Class<? extends WeixinMessage> match(MessageKey messageKey) {
return messageClassMap.get(messageKey);
}
@Override
public void regist(MessageKey messageKey, Class<?> messageClass) {
public void regist(MessageKey messageKey,
Class<? extends WeixinMessage> messageClass) {
Class<?> clazz = messageClassMap.get(messageKey);
if (clazz != null) {
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.WeixinMessageHandler;
import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.TextResponse;
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输出消息信息
@ -101,7 +102,7 @@ public class WeixinMessageDispatcher {
public WeixinMessageDispatcher(WeixinMessageMatcher 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 {
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);
}
Class<? extends WeixinMessage> targetClass = messageMatcher
.match(messageKey);
Object message = messageRead(request.getOriginalContent(), targetClass);
logger.info("define '{}' matched '{}'", messageKey, targetClass);
MessageHandlerExecutor handlerExecutor = getHandlerExecutor(context,
request, messageKey, message, cruxMessage.getNodeNames());
@ -178,7 +177,7 @@ public class WeixinMessageDispatcher {
protected void noHandlerFound(ChannelHandlerContext context,
WeixinRequest request, Object message) {
if (isDebug) {
if (message instanceof String) {
if (message == null) {
context.writeAndFlush(
new TextResponse(request.getOriginalContent()
.replaceAll("\\!\\[CDATA\\[", "")
@ -357,13 +356,16 @@ public class WeixinMessageDispatcher {
* @return 消息对象
* @throws WeixinException
*/
protected Object messageRead(String message, Class<?> clazz)
throws WeixinException {
protected Object messageRead(String message,
Class<? extends WeixinMessage> clazz) throws WeixinException {
if (clazz == null) {
return null;
}
try {
Source source = new StreamSource(new ByteArrayInputStream(
message.getBytes(Consts.UTF_8)));
JAXBElement<?> jaxbElement = getUnmarshaller(clazz).unmarshal(
source, clazz);
JAXBElement<? extends WeixinMessage> jaxbElement = getUnmarshaller(
clazz).unmarshal(source, clazz);
return jaxbElement.getValue();
} catch (JAXBException e) {
throw new WeixinException(e);
@ -378,7 +380,7 @@ public class WeixinMessageDispatcher {
* @return 消息转换器
* @throws WeixinException
*/
protected Unmarshaller getUnmarshaller(Class<?> clazz)
protected Unmarshaller getUnmarshaller(Class<? extends WeixinMessage> clazz)
throws WeixinException {
Unmarshaller unmarshaller = messageUnmarshaller.get(clazz);
if (unmarshaller == null) {
@ -445,7 +447,8 @@ public class WeixinMessageDispatcher {
this.beanFactory = beanFactory;
}
public void registMessageClass(MessageKey messageKey, Class<?> messageClass) {
public void registMessageClass(MessageKey messageKey,
Class<? extends WeixinMessage> messageClass) {
messageMatcher.regist(messageKey, messageClass);
}

View File

@ -1,5 +1,7 @@
package com.foxinmy.weixin4j.dispatcher;
import com.foxinmy.weixin4j.request.WeixinMessage;
/**
* 微信消息匹配
*
@ -17,7 +19,7 @@ public interface WeixinMessageMatcher {
* 消息key
* @return 消息类型
*/
public Class<?> match(MessageKey messageKey);
public Class<? extends WeixinMessage> match(MessageKey messageKey);
/**
* 注册消息类型程序没有及时更新而微信又产生了新的消息类型
@ -27,5 +29,6 @@ public interface WeixinMessageMatcher {
* @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 com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.WeixinResponse;
@ -16,7 +17,8 @@ import com.foxinmy.weixin4j.response.WeixinResponse;
* @see
*/
@SuppressWarnings("unchecked")
public abstract class MessageHandlerAdapter<M> implements WeixinMessageHandler {
public abstract class MessageHandlerAdapter<M extends WeixinMessage> implements
WeixinMessageHandler {
@Override
public boolean canHandle(WeixinRequest request, Object message,

View File

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

View File

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