weixin4j-server:消息拦截器和处理器支持泛型

This commit is contained in:
jinyu 2015-05-15 12:51:19 +08:00
parent 33d5addc18
commit b6ec2485c9
18 changed files with 283 additions and 206 deletions

View File

@ -280,3 +280,7 @@
* 2015-05-13
+ **weixin4j-server**: 新增了许多被动消息类型
* 2015-05-15
+ **weixin4j-server**: 消息拦截器和处理器支持泛型

View File

@ -28,4 +28,8 @@
* 2015-05-13
+ 新增了许多被动消息类型
+ 新增了许多被动消息类型
* 2015-05-15
+ **weixin4j-server**: 消息拦截器和处理器支持泛型

View File

@ -8,7 +8,6 @@ import org.slf4j.LoggerFactory;
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.request.WeixinRequest;
import com.foxinmy.weixin4j.response.WeixinResponse;
@ -49,7 +48,7 @@ public class MessageHandlerExecutor {
return messageHandler;
}
public boolean applyPreHandle(WeixinRequest request, WeixinMessage message)
public boolean applyPreHandle(WeixinRequest request, String message)
throws WeixinException {
if (messageInterceptors != null) {
for (int i = 0; i < messageInterceptors.length; i++) {
@ -66,7 +65,7 @@ public class MessageHandlerExecutor {
}
public void applyPostHandle(WeixinRequest request, WeixinResponse response,
WeixinMessage message) throws WeixinException {
String message) throws WeixinException {
if (messageInterceptors == null) {
return;
}
@ -77,8 +76,8 @@ public class MessageHandlerExecutor {
}
}
public void triggerAfterCompletion(WeixinRequest request,
WeixinMessage message, WeixinException ex) throws WeixinException {
public void triggerAfterCompletion(WeixinRequest request, String message,
WeixinException exception) throws WeixinException {
if (messageInterceptors == null) {
return;
}
@ -86,7 +85,7 @@ public class MessageHandlerExecutor {
WeixinMessageInterceptor interceptor = messageInterceptors[i];
try {
interceptor.afterCompletion(context, request, message,
messageHandler, ex);
messageHandler, exception);
} catch (WeixinException e) {
logger.error(
"MessageInterceptor.afterCompletion threw exception", e);

View File

@ -0,0 +1,69 @@
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;
}
}

View File

@ -16,7 +16,6 @@ import com.foxinmy.weixin4j.bean.BeanFactory;
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.request.WeixinRequest;
import com.foxinmy.weixin4j.response.WeixinResponse;
import com.foxinmy.weixin4j.util.ClassUtil;
@ -65,7 +64,7 @@ public class WeixinMessageDispatcher {
}
public void doDispatch(final ChannelHandlerContext context,
final WeixinRequest request, final WeixinMessage message)
final WeixinRequest request, final String message)
throws WeixinException {
MessageHandlerExecutor handlerExecutor = getHandlerExecutor(context,
request, message);
@ -94,14 +93,14 @@ public class WeixinMessageDispatcher {
}
protected void noHandlerFound(ChannelHandlerContext ctx,
WeixinRequest request, WeixinMessage message) {
WeixinRequest request, String message) {
ctx.writeAndFlush(HttpUtil.createHttpResponse(null, NOT_FOUND, null))
.addListener(ChannelFutureListener.CLOSE);
}
protected MessageHandlerExecutor getHandlerExecutor(
ChannelHandlerContext context, WeixinRequest request,
WeixinMessage message) throws WeixinException {
ChannelHandlerContext context, WeixinRequest request, String message)
throws WeixinException {
WeixinMessageHandler messageHandler = null;
WeixinMessageHandler[] messageHandlers = getMessageHandlers();
if (messageHandlers == null) {

View File

@ -1,12 +1,11 @@
package com.foxinmy.weixin4j.handler;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.BlankResponse;
import com.foxinmy.weixin4j.response.WeixinResponse;
public class BlankMessageHandler extends MessageHandlerAdapter {
public class BlankMessageHandler implements WeixinMessageHandler {
public final static BlankMessageHandler global = new BlankMessageHandler();
@ -15,7 +14,13 @@ public class BlankMessageHandler extends MessageHandlerAdapter {
}
@Override
public WeixinResponse doHandle(WeixinRequest request, WeixinMessage message)
public boolean canHandle(WeixinRequest request, String message)
throws WeixinException {
return true;
}
@Override
public WeixinResponse doHandle(WeixinRequest request, String message)
throws WeixinException {
return BlankResponse.global;
}

View File

@ -1,23 +1,27 @@
package com.foxinmy.weixin4j.handler;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.TextResponse;
import com.foxinmy.weixin4j.response.WeixinResponse;
public class DebugMessageHandler extends MessageHandlerAdapter {
public class DebugMessageHandler implements WeixinMessageHandler {
public static final DebugMessageHandler global = new DebugMessageHandler();
private DebugMessageHandler(){
private DebugMessageHandler() {
}
@Override
public WeixinResponse doHandle(WeixinRequest request, WeixinMessage message)
public boolean canHandle(WeixinRequest request, String message)
throws WeixinException {
return new TextResponse(String.format("%s,%s", request,
message));
return true;
}
@Override
public WeixinResponse doHandle(WeixinRequest request, String message)
throws WeixinException {
return new TextResponse(message);
}
}

View File

@ -1,12 +1,32 @@
package com.foxinmy.weixin4j.handler;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.dispatcher.WeixinMessageAdapter;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.WeixinResponse;
public abstract class MessageHandlerAdapter implements WeixinMessageHandler {
public abstract class MessageHandlerAdapter<M> extends WeixinMessageAdapter<M>
implements WeixinMessageHandler {
private M message;
@Override
public boolean canHandle(WeixinRequest request, WeixinMessage message) {
return true;
public boolean canHandle(WeixinRequest request, String message)
throws WeixinException {
this.message = super.messageRead(message);
return canHandle0(request, message, this.message);
}
public abstract boolean canHandle0(WeixinRequest request, String message,
M m) throws WeixinException;
@Override
public WeixinResponse doHandle(WeixinRequest request, String message)
throws WeixinException {
return doHandle0(request, message, this.message);
}
public abstract WeixinResponse doHandle0(WeixinRequest request,
String message, M m) throws WeixinException;
}

View File

@ -1,7 +1,6 @@
package com.foxinmy.weixin4j.handler;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.WeixinResponse;
@ -25,7 +24,8 @@ public interface WeixinMessageHandler {
* 微信消息
* @return
*/
public boolean canHandle(WeixinRequest request, WeixinMessage message);
public boolean canHandle(WeixinRequest request, String message)
throws WeixinException;
/**
* 处理请求
@ -36,6 +36,6 @@ public interface WeixinMessageHandler {
* 微信消息
* @return
*/
public WeixinResponse doHandle(WeixinRequest request, WeixinMessage message)
public WeixinResponse doHandle(WeixinRequest request, String message)
throws WeixinException;
}

View File

@ -2,33 +2,60 @@ package com.foxinmy.weixin4j.interceptor;
import io.netty.channel.ChannelHandlerContext;
import com.foxinmy.weixin4j.dispatcher.WeixinMessageAdapter;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.handler.WeixinMessageHandler;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.WeixinResponse;
public abstract class MessageInterceptorAdapter implements
WeixinMessageInterceptor {
/**
* 消息拦截适配
*
* @className MessageInterceptorAdapter
* @author jy
* @date 2015年5月14日
* @since JDK 1.7
* @see
*/
public abstract class MessageInterceptorAdapter<M> extends
WeixinMessageAdapter<M> implements WeixinMessageInterceptor {
private M message;
@Override
public boolean preHandle(ChannelHandlerContext context,
WeixinRequest request, WeixinMessage message,
WeixinRequest request, final String message,
WeixinMessageHandler handler) throws WeixinException {
return true;
this.message = super.messageRead(message);
return preHandle0(context, request, this.message, handler);
}
public abstract boolean preHandle0(ChannelHandlerContext context,
WeixinRequest request, M message, WeixinMessageHandler handler)
throws WeixinException;
@Override
public void postHandle(ChannelHandlerContext context,
WeixinRequest request, WeixinResponse response,
WeixinMessage message, WeixinMessageHandler handler)
throws WeixinException {
WeixinRequest request, WeixinResponse response, String message,
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
public void afterCompletion(ChannelHandlerContext context,
WeixinRequest request, WeixinMessage message,
WeixinRequest request, String message,
WeixinMessageHandler handler, WeixinException exception)
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;
}

View File

@ -4,7 +4,6 @@ import io.netty.channel.ChannelHandlerContext;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.handler.WeixinMessageHandler;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.WeixinResponse;
@ -22,7 +21,7 @@ public interface WeixinMessageInterceptor {
/**
* 执行handler前
*
* @param ctx
* @param context
* 通道环境
* @param request
* 微信请求
@ -33,14 +32,14 @@ public interface WeixinMessageInterceptor {
* @return 返回true执行下一个拦截器
* @throws WeixinException
*/
boolean preHandle(ChannelHandlerContext ctx, WeixinRequest request,
WeixinMessage message, WeixinMessageHandler handler)
boolean preHandle(ChannelHandlerContext context, WeixinRequest request,
String message, WeixinMessageHandler handler)
throws WeixinException;
/**
* 执行handler后
*
* @param ctx
* @param context
* 通道环境
* @param request
* 微信请求
@ -52,14 +51,14 @@ public interface WeixinMessageInterceptor {
* 消息处理器
* @throws WeixinException
*/
void postHandle(ChannelHandlerContext ctx, WeixinRequest request,
WeixinResponse response, WeixinMessage message,
void postHandle(ChannelHandlerContext context, WeixinRequest request,
WeixinResponse response, String message,
WeixinMessageHandler handler) throws WeixinException;
/**
* 全部执行后
*
* @param ctx
* @param context
* 通道环境
* @param request
* 微信请求
@ -71,7 +70,7 @@ public interface WeixinMessageInterceptor {
* 执行异常
* @throws WeixinException
*/
void afterCompletion(ChannelHandlerContext ctx, WeixinRequest request,
WeixinMessage message, WeixinMessageHandler handler,
void afterCompletion(ChannelHandlerContext context, WeixinRequest request,
String message, WeixinMessageHandler handler,
WeixinException exception) throws WeixinException;
}

View File

@ -4,7 +4,7 @@ import java.io.Serializable;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElementWrapper;
/**
* 弹出拍照或者相册发图的事件推送(pic_sysphoto|pic_photo_or_album|pic_weixin)
@ -53,7 +53,8 @@ public class MenuPhotoEventMessage extends MenuEventMessage {
/**
* 图片列表
*/
@XmlElement(name = "PicList")
@XmlElementWrapper(name = "PicList")
@XmlElement(name = "item")
private List<PictureItem> items;
public int getCount() {
@ -79,7 +80,6 @@ public class MenuPhotoEventMessage extends MenuEventMessage {
* @since JDK 1.7
* @see
*/
@XmlRootElement(name = "item")
public static class PictureItem implements Serializable {
private static final long serialVersionUID = -7636697449096645590L;
@ -90,6 +90,10 @@ public class MenuPhotoEventMessage extends MenuEventMessage {
@XmlElement(name = "PicMd5Sum")
private String md5;
public String getMd5() {
return md5;
}
@Override
public String toString() {
return "PictureItem [md5=" + md5 + "]";

View File

@ -3,7 +3,6 @@ package com.foxinmy.weixin4j.request;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* 基本被动消息
@ -14,7 +13,6 @@ import javax.xml.bind.annotation.XmlRootElement;
* @since JDK 1.7
* @see
*/
@XmlRootElement(name = "xml")
public class WeixinMessage implements Serializable {
private static final long serialVersionUID = 7761192742840031607L;
@ -22,27 +20,33 @@ public class WeixinMessage implements Serializable {
/**
* 开发者微信号
*/
@XmlElement(name = "ToUserName")
private String toUserName;
/**
* 发送方账号 即用户的openid
*/
@XmlElement(name = "FromUserName")
private String fromUserName;
/**
* 消息创建时间 系统毫秒数
*/
@XmlElement(name = "CreateTime")
private long createTime;
/**
* 消息类型
*
*/
@XmlElement(name = "MsgType")
private String msgType;
/**
* 消息ID 可用于排重
*/
@XmlElement(name = "MsgId")
private long msgId;
/**
* 企业号独有的应用ID
*/
@XmlElement(name = "AgentID")
private String agentId;
public WeixinMessage() {
@ -57,56 +61,26 @@ public class WeixinMessage implements Serializable {
return toUserName;
}
@XmlElement(name = "ToUserName")
public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}
public String getFromUserName() {
return fromUserName;
}
@XmlElement(name = "FromUserName")
public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}
public long getCreateTime() {
return createTime;
}
@XmlElement(name = "CreateTime")
public void setCreateTime(long createTime) {
this.createTime = createTime;
}
public String getMsgType() {
return msgType;
}
@XmlElement(name = "MsgType")
public void setMsgType(String msgType) {
this.msgType = msgType;
}
public long getMsgId() {
return msgId;
}
@XmlElement(name = "MsgId")
public void setMsgId(long msgId) {
this.msgId = msgId;
}
public String getAgentId() {
return agentId;
}
@XmlElement(name = "AgentID")
public void setAgentId(String agentId) {
this.agentId = agentId;
}
@Override
public int hashCode() {
final int prime = 31;

View File

@ -17,17 +17,10 @@ public class WeixinRequest implements Serializable, Cloneable {
private static final long serialVersionUID = -9157395300510879866L;
// 以下字段是加密方式为安全模式时的参数
/**
* 加密后的内容
* 请求的方式
*/
private String encryptContent;
/**
* 加密类型
*
* @see com.foxinmy.weixin4j.type.EncryptType
*/
private EncryptType encryptType;
private String method;
// 以下字段每次被动消息时都会带上
/**
@ -50,85 +43,72 @@ public class WeixinRequest implements Serializable, Cloneable {
* AES模式下消息签名
*/
private String msgSignature;
/**
* 加密类型(POST时存在)
*
* @see com.foxinmy.weixin4j.type.EncryptType
*/
private EncryptType encryptType;
/**
* xml消息明文主体
*/
private String originalContent;
/**
* 请求的方式
* xml消息密文主体(AES时存在)
*/
private String method;
private String encryptContent;
public String getEncryptContent() {
return encryptContent;
}
public void setEncryptContent(String encryptContent) {
this.encryptContent = encryptContent;
}
public EncryptType getEncryptType() {
return encryptType;
}
public void setEncryptType(EncryptType encryptType) {
public WeixinRequest(String method, EncryptType encryptType,
String echoStr, String timeStamp, String nonce, String signature,
String msgSignature, String originalContent, String encryptContent) {
this.method = method;
this.encryptType = encryptType;
}
public String getEchoStr() {
return echoStr;
}
public void setEchoStr(String echoStr) {
this.echoStr = echoStr;
}
public String getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(String timeStamp) {
this.timeStamp = timeStamp;
}
public String getNonce() {
return nonce;
}
public void setNonce(String nonce) {
this.nonce = nonce;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getMsgSignature() {
return msgSignature;
}
public void setMsgSignature(String msgSignature) {
this.msgSignature = msgSignature;
}
public String getOriginalContent() {
return originalContent;
}
public void setOriginalContent(String originalContent) {
this.originalContent = originalContent;
this.encryptContent = encryptContent;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
public String getEchoStr() {
return echoStr;
}
public String getTimeStamp() {
return timeStamp;
}
public String getNonce() {
return nonce;
}
public String getSignature() {
return signature;
}
public String getMsgSignature() {
return msgSignature;
}
public EncryptType getEncryptType() {
return encryptType;
}
public String getOriginalContent() {
return originalContent;
}
public String getEncryptContent() {
return encryptContent;
}
@Override

View File

@ -44,8 +44,6 @@ public class WeixinMessageDecoder extends
protected void decode(ChannelHandlerContext ctx, FullHttpRequest req,
List<Object> out) throws WeixinException {
String content = req.content().toString(Consts.UTF_8);
WeixinRequest message = new WeixinRequest();
message.setMethod(req.getMethod().name());
QueryStringDecoder queryDecoder = new QueryStringDecoder(req.getUri(),
true);
log.info("\n=================receive request=================");
@ -53,40 +51,35 @@ public class WeixinMessageDecoder extends
log.info("{}", req.getUri());
log.info("{}", content);
Map<String, List<String>> parameters = queryDecoder.parameters();
String encryptType = parameters.containsKey("encrypt_type") ? parameters
.get("encrypt_type").get(0) : EncryptType.RAW.name();
message.setEncryptType(EncryptType.valueOf(encryptType.toUpperCase()));
EncryptType encryptType = parameters.containsKey("encrypt_type") ? EncryptType
.valueOf(parameters.get("encrypt_type").get(0).toUpperCase())
: EncryptType.RAW;
String echoStr = parameters.containsKey("echostr") ? parameters.get(
"echostr").get(0) : "";
message.setEchoStr(echoStr);
String timeStamp = parameters.containsKey("timestamp") ? parameters
.get("timestamp").get(0) : "";
message.setTimeStamp(timeStamp);
String nonce = parameters.containsKey("nonce") ? parameters
.get("nonce").get(0) : "";
message.setNonce(nonce);
String signature = parameters.containsKey("signature") ? parameters
.get("signature").get(0) : "";
message.setSignature(signature);
String msgSignature = parameters.containsKey("msg_signature") ? parameters
.get("msg_signature").get(0) : "";
message.setMsgSignature(msgSignature);
String originalContent = content;
String encryptContent = null;
if (!content.isEmpty()) {
if (message.getEncryptType() == EncryptType.AES) {
if (encryptType == EncryptType.AES) {
if (StringUtil.isBlank(aesToken.getAesKey())
|| StringUtil.isBlank(aesToken.getAppid())) {
throw new WeixinException(
"AESEncodingKey or AppId not be null in AES mode");
}
String encryptContent = EncryptMessageHandler.parser(content);
message.setEncryptContent(encryptContent);
message.setOriginalContent(MessageUtil.aesDecrypt(
aesToken.getAppid(), aesToken.getAesKey(),
encryptContent));
} else {
message.setOriginalContent(content);
encryptContent = EncryptMessageHandler.parser(content);
originalContent = MessageUtil.aesDecrypt(aesToken.getAppid(),
aesToken.getAesKey(), encryptContent);
}
}
out.add(message);
out.add(new WeixinRequest(req.getMethod().name(), encryptType, echoStr,
timeStamp, nonce, signature, msgSignature, originalContent,
encryptContent));
}
}

View File

@ -11,8 +11,11 @@ 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.LoggerFactory;
@ -23,7 +26,6 @@ import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.type.EncryptType;
import com.foxinmy.weixin4j.util.ClassUtil;
import com.foxinmy.weixin4j.util.Consts;
import com.foxinmy.weixin4j.util.HttpUtil;
import com.foxinmy.weixin4j.util.MessageUtil;
@ -44,17 +46,11 @@ public class WeixinRequestHandler extends
private final AesToken aesToken;
private final WeixinMessageDispatcher messageDispatcher;
private final JAXBContext jaxbContext;
public WeixinRequestHandler(AesToken aesToken,
WeixinMessageDispatcher messageDispatcher) throws WeixinException {
this.aesToken = aesToken;
this.messageDispatcher = messageDispatcher;
try {
jaxbContext = JAXBContext.newInstance(WeixinMessage.class);
} catch (JAXBException e) {
throw new WeixinException(e);
}
}
public void channelReadComplete(ChannelHandlerContext ctx) {
@ -112,12 +108,16 @@ public class WeixinRequestHandler extends
.addListener(ChannelFutureListener.CLOSE);
return;
}
WeixinMessage weixinMessage = null;
final String message = request.getOriginalContent();
WeixinMessage weixinMessage;
try {
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
weixinMessage = (WeixinMessage) jaxbUnmarshaller
.unmarshal(new ByteArrayInputStream(request
.getOriginalContent().getBytes(Consts.UTF_8)));
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);
}
@ -129,10 +129,6 @@ public class WeixinRequestHandler extends
ctx.channel().attr(Consts.ACCOUNTOPENID_KEY)
.set(weixinMessage.getToUserName());
}
final WeixinRequest cloneRequest = (WeixinRequest) ClassUtil
.deepClone(request);
final WeixinMessage cloneMessage = (WeixinMessage) ClassUtil
.deepClone(weixinMessage);
messageDispatcher.doDispatch(ctx, cloneRequest, cloneMessage);
messageDispatcher.doDispatch(ctx, request, message);
}
}

View File

@ -77,7 +77,7 @@ public class WeixinResponseEncoder extends
aesToken.getAesKey(), content.toString());
String msgSignature = MessageUtil.signature(
aesToken.getToken(), nonce, timestamp, encrtypt);
content.delete(0, content.length() - 1);
content.delete(0, content.length());
content.append("<xml>");
content.append(String.format("<Nonce><![CDATA[%s]]></Nonce>",
nonce));

View File

@ -5,10 +5,10 @@ import io.netty.channel.ChannelHandlerContext;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.handler.BlankMessageHandler;
import com.foxinmy.weixin4j.handler.DebugMessageHandler;
import com.foxinmy.weixin4j.handler.MessageHandlerAdapter;
import com.foxinmy.weixin4j.handler.WeixinMessageHandler;
import com.foxinmy.weixin4j.interceptor.MessageInterceptorAdapter;
import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.message.TextMessage;
import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.TextResponse;
import com.foxinmy.weixin4j.response.WeixinResponse;
@ -57,18 +57,18 @@ public class MessageServerStartup {
* @throws WeixinException
*/
public void test3() throws WeixinException {
// 回复文本消息
WeixinMessageHandler messageHandler = new WeixinMessageHandler() {
// 文本消息回复
WeixinMessageHandler messageHandler = new MessageHandlerAdapter<TextMessage>() {
@Override
public WeixinResponse doHandle(WeixinRequest request,
WeixinMessage message) throws WeixinException {
return new TextResponse("HelloWorld!");
public boolean canHandle0(WeixinRequest request, String message,
TextMessage m) throws WeixinException {
return true;
}
@Override
public boolean canHandle(WeixinRequest request,
WeixinMessage message) {
return message.getMsgType().equals("text");
public WeixinResponse doHandle0(WeixinRequest request,
String message, TextMessage m) throws WeixinException {
return new TextResponse("HelloWorld!");
}
};
// 当消息类型为文本(text)时回复HelloWorld, 否则回复调试消息
@ -85,26 +85,26 @@ public class MessageServerStartup {
public void test5() throws WeixinException {
// 拦截所有请求
WeixinMessageInterceptor interceptor = new MessageInterceptorAdapter() {
WeixinMessageInterceptor interceptor = new WeixinMessageInterceptor() {
@Override
public boolean preHandle(ChannelHandlerContext context,
WeixinRequest request, WeixinMessage message,
WeixinRequest request, String message,
WeixinMessageHandler handler) throws WeixinException {
context.write(new TextResponse("所有消息被拦截了!"));
context.writeAndFlush(new TextResponse("所有消息被拦截了!"));
return false;
}
@Override
public void postHandle(ChannelHandlerContext context,
WeixinRequest request, WeixinResponse response,
WeixinMessage message, WeixinMessageHandler handler)
String message, WeixinMessageHandler handler)
throws WeixinException {
System.err.println("preHandle返回为true,执行handler后");
}
@Override
public void afterCompletion(ChannelHandlerContext context,
WeixinRequest request, WeixinMessage message,
WeixinRequest request, String message,
WeixinMessageHandler handler, WeixinException exception)
throws WeixinException {
System.err.println("请求处理完毕");
@ -115,6 +115,6 @@ public class MessageServerStartup {
}
public static void main(String[] args) throws WeixinException {
new MessageServerStartup().test5();
new MessageServerStartup().test1();
}
}