weixin4j-server: WeixinServerBootstrap 构造函数支持多个公众号 &
MessageHandlerAdapter 声明时限定泛型为 WeixinMessage 的子类
This commit is contained in:
parent
357952e70e
commit
ea03c92eb0
@ -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`的子类
|
||||||
@ -56,4 +56,10 @@
|
|||||||
|
|
||||||
* 2015-07-04
|
* 2015-07-04
|
||||||
|
|
||||||
+ released 1.0.3
|
+ released 1.0.3
|
||||||
|
|
||||||
|
* 2015-07-31
|
||||||
|
|
||||||
|
`WeixinServerBootstrap` 构造函数支持多个公众号
|
||||||
|
|
||||||
|
`MessageHandlerAdapter` 声明时限定泛型为`WeixinMessage`的子类
|
||||||
@ -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 '"
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user