
top.hmtools.wxmp.core.DefaultWxmpMessageHandle Maven / Gradle / Ivy
The newest version!
package top.hmtools.wxmp.core;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.hmtools.wxmp.core.annotation.WxmpController;
import top.hmtools.wxmp.core.annotation.WxmpMessage;
import top.hmtools.wxmp.core.annotation.WxmpRequestMapping;
import top.hmtools.wxmp.core.model.MessageMetaInfo;
import top.hmtools.wxmp.core.model.message.BaseMessage;
import top.hmtools.wxmp.core.model.message.TempMessage;
import top.hmtools.wxmp.core.model.message.enums.Event;
import top.hmtools.wxmp.core.model.message.enums.MsgType;
/**
* 核心的微信消息(事件)处理工具
* FIXME
试验版,后期可能需要改良
* @author HyboWork
*
*/
public class DefaultWxmpMessageHandle {
private final Logger logger = LoggerFactory.getLogger(DefaultWxmpMessageHandle.class);
/**
* 消息类型与消息元数据字典容器
*/
private HashMap msgTypeMap = new HashMap<>();
/**
* 事件类型与消息元数据字典容器
*/
private HashMap eventMap = new HashMap<>();
/**
* 解析并添加微信xml消息处理器
*
必须是被{@link top.hmtools.wxmp.core.annotation.WxmpController}注解修饰的类
*
其中的处理方法必须是被 {@link top.hmtools.wxmp.core.annotation.WxmpRequestMapping}注解修饰
*
其中处理方法只能有一个形式参数,且该形式参数的类必须继承自 {@link top.hmtools.wxmp.core.model.message.BaseMessage},且该类必须被注解 {@link top.hmtools.wxmp.core.annotation.WxmpMessage} 注解修饰
* @param obj
*/
public void addMessageMetaInfo(Object obj){
//检查参数是否为null
if(obj == null){
this.logger.error("入参为null,忽略……");
return;
}
//检查obj是否被 top.hmtools.wxmp.core.annotation.WxmpController 注解修饰,没有则打印日志并忽略(或者抛出运行时异常??)
WxmpController wxmpController = obj.getClass().getAnnotation(WxmpController.class);
if(wxmpController == null){
throw new RuntimeException(obj.getClass()+"没有被注解:"+WxmpController.class+"修饰");
}
//提取该对象实例中所有被 top.hmtools.wxmp.core.annotation.WxmpRequestMapping 注解修饰的方法
Method[] methods = obj.getClass().getMethods();
for(Method method:methods){
WxmpRequestMapping wxmpRequestMapping = method.getAnnotation(WxmpRequestMapping.class);
if(wxmpRequestMapping != null){
//将提取出的 方法反射 信息 组装成 top.hmtools.wxmp.core.model.MessageMetaInfo 对象实例
MessageMetaInfo messageMetaInfo = new MessageMetaInfo();
messageMetaInfo.setMethod(method);
messageMetaInfo.setObj(obj);
//提取方法 及其 形式参数
Class>[] parameterTypes = method.getParameterTypes();
if(parameterTypes == null || parameterTypes.length<1){
throw new RuntimeException(obj.getClass()+"的method:"+method.getName()+"没有形参");
}
if(!BaseMessage.class.isAssignableFrom(parameterTypes[0])){
throw new RuntimeException(obj.getClass()+"的method:"+method.getName()+"的形式参数:"+parameterTypes[0]+"没有继承"+BaseMessage.class);
}
Class extends BaseMessage> parameterType = (Class extends BaseMessage>) parameterTypes[0];
messageMetaInfo.setMessageBeanClass(parameterType);
WxmpMessage wxmpMessage = parameterType.getAnnotation(WxmpMessage.class);
if(wxmpMessage == null){
throw new RuntimeException(obj.getClass()+"的method:"+method.getName()+"的形式参数:"+parameterType+"没有被注解:"+WxmpMessage.class+"修饰");
}
//检查容器里是否已存在,已存在则抛出运行时异常(不能同时存在2个以上处理同一种消息结构的方法),不存在则存入容器
MsgType msgType = wxmpMessage.msgType();
if(msgType == null){
throw new RuntimeException(obj.getClass()+"的method:"+method.getName()+"的形式参数:"+parameterType+"的注解:"+WxmpMessage.class+"没有设置MsgType值");
}
//如果消息类型是 事件
if(msgType.equals(MsgType.event)){
Event event = wxmpMessage.event();
if(StringUtils.isEmpty(event.getName())){
throw new RuntimeException(obj.getClass()+"的method:"+method.getName()+"的形式参数:"+parameterType+"的注解:"+WxmpMessage.class+"没有设置Event值");
}
if(this.eventMap.containsKey(event)){
// this.logger.error("当前:{}",parameterType);//当前
// this.logger.error("已有:{}",this.eventMap.get(event).getMethod().getParameterTypes()[0]);//已有
this.logger.error("当前:{}",method);//当前
this.logger.error("已有:{}",this.eventMap.get(event).getMethod());//已有
throw new RuntimeException("存在多个Event值为:"+event+"的消息元数据");
}
this.eventMap.put(event, messageMetaInfo);
continue;
}
if(this.msgTypeMap.containsKey(msgType)){
// this.logger.error("{}",parameterType);//当前
// this.logger.error("{}",this.msgTypeMap.get(msgType).getMethod().getParameterTypes()[0]);//已有
this.logger.error("当前:{}",method);//当前
this.logger.error("已有:{}",this.msgTypeMap.get(msgType).getMethod());//已有
throw new RuntimeException("存在多个MsgType值为:"+msgType+"的消息元数据");
}
this.msgTypeMap.put(msgType, messageMetaInfo);
}
}
}
/**
* 解析并处理从微信服务器接收到的xml字符串数据
* @param xml
* @return
*/
public Object processXmlData(String xml){
if(this.logger.isDebugEnabled()){
this.logger.debug("处理xml消息,xml原文是:{}",xml);
}
//检查入参
if(StringUtils.isEmpty(xml)){
throw new IllegalArgumentException("入参为空");
}
//转化成临时消息实体对象实例
TempMessage tempMessage = new TempMessage();
tempMessage.loadDataFromXml(xml);
//根据消息类型、事件类型从容器中提取出对应得处理方法
MsgType msgType = tempMessage.getMsgType();
if(msgType == null){
throw new RuntimeException("该消息中没有MsgType元素值");
}
MessageMetaInfo messageMetaInfo = null;
if(msgType.equals(MsgType.event)){
//事件
Event event = tempMessage.getEvent();
if(event == null){
throw new RuntimeException("该事件消息中没有Event元素值");
}
messageMetaInfo = this.eventMap.get(event);
}else{
//非事件
messageMetaInfo = this.msgTypeMap.get(msgType);
}
if(messageMetaInfo == null){
this.logger.error("无法解析该xml消息:{}",xml);
return null;
}
//通过反射机制执行后,返回其返回的结果数据
Class extends BaseMessage> messageBeanClass = messageMetaInfo.getMessageBeanClass();
try {
BaseMessage baseMessage = messageBeanClass.newInstance();
baseMessage.loadDataFromXml(xml);
return messageMetaInfo.getMethod().invoke(messageMetaInfo.getObj(), baseMessage);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public Logger getLogger() {
return logger;
}
/**
* 消息类型与消息元数据字典容器
* @return
*/
public HashMap getMsgTypeMap() {
return msgTypeMap;
}
/**
* 事件类型与消息元数据字典容器
* @return
*/
public HashMap getEventMap() {
return eventMap;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy