您的位置:首页 > 其它

责任链模式和工厂模式在处理被动响应消息中的应用

2015-03-05 17:08 501 查看
在公众号建设中,发送被动响应消息是最核心的环节,用户主动发给微信的消息经微信服务器处理后,统一变成xml格式的报文,微信公众平台后台需要对这些报文进行分别处理,然后组织响应报文响应给用户,同时针对某些特殊操作的行为需要修改数据库的某些信息。

综合来看,微信公众平台对上行消息的处理流程分为以下几个部分:1)上行消息入库;2)数据库状态修改;3)返回应答消息;4)应答消息入库。

这四个部分是一个串行流程,很适合用责任链模式处理,责任链模式的相关内容这里不仔细讲解了(读者感兴趣可以上网去查),它的使用大致可以总结为:1)定义抽象类,例如AbstractMessageHandler,持有自己的引用,定义公用的抽象方法handleMessage();2)定义具体处理类,例如数据库处理类、状态处理器类、应答消息处理器类等,分别集成抽象类,实现各自的处理方法;3)使用时需要制定责任链模式前驱对象的后继对象,才能将下一步操作转交出去。

(1)责任链模式的实际应用如下:

定义抽象类: (可以看到它持有自己的引用)

/**
*
* @类名: AbstracMessageHandler.java
* @描述:责任链模式的抽象处理器
* @作者: mxyanx
* @修改日期: 2015年3月2日
*/
public abstract class AbstractMessageHandler
{

protected AbstractMessageHandler successor;

public abstract String handleMessage(String requestXmlData,BaseMessage baseMessage,String responseMessage) throws IOException;

public AbstractMessageHandler getSuccessor()
{
return successor;
}

public void setSuccessor(AbstractMessageHandler successor)
{
this.successor = successor;
}

}
定义具体实现类之一:消息入库

/**
*
* @类名: Message2DBHandler.java
* @描述:责任链模式处理的第一个环节,专门针对消息入库
* @作者: mxyanx
* @修改日期: 2015年3月2日
*/
@Component
public class Message2DBHandler extends AbstractMessageHandler
{

private static final Logger logger = Logger.getLogger(Message2DBHandler.class);

@Override
public String handleMessage(String requestXmlData, BaseMessage baseMessage,String responseMessageStr) throws IOException
{
//数据库处理
......
//如果有后继处理器,则返回下一个处理器的结果
if(this.getSuccessor() != null){
return this.getSuccessor().handleMessage(requestXmlData, baseMessage,responseMessageStr);
}else{
return responseMessageStr;
}
}
}


定义具体实现类之二:状态处理

/**
*
* @类名: MessageStatusHandler.java
* @描述:责任链模式处理的第二个环节,专门针对事件类型的消息修改状态
* @作者: mxyanx
* @修改日期: 2015年3月2日
*/
@Component
public class MessageStatusHandler extends AbstractMessageHandler
{

private static final Logger logger = Logger.getLogger(<span style="font-family: Arial, Helvetica, sans-serif;">MessageStatusHandler</span>.class);

@Override
public String handleMessage(String requestXmlData, BaseMessage baseMessage,String responseMessageStr) throws IOException
{
//状态处理
if (baseMessage.getMsgType().equalsIgnoreCase("event"))
{
......
}
//如果有后继处理器,则返回下一个处理器的结果
if(this.getSuccessor() != null){
return this.getSuccessor().handleMessage(requestXmlData, baseMessage,responseMessageStr);
}else{
return responseMessageStr;
}
}
}


定义具体实现类之三:组织被动响应消息返回

/**
*
* @类名: MessageResponseHandler.java
* @描述:责任链模式处理的第三个环节,组织被动响应消息
* @作者: mxyanx
* @修改日期: 2015年3月2日
*/
@Component
public class MessageResponseHandler extends AbstractMessageHandler
{

private static final Logger logger = Logger.getLogger(MessageResponseHandler.class);

@Override
public String handleMessage(String requestXmlData, BaseMessage baseMessage,String responseMessageStr) throws IOException
{
//生成被动响应消息
......
//如果有后继处理器,则返回下一个处理器的结果
if(this.getSuccessor() != null){
return this.getSuccessor().handleMessage(requestXmlData, baseMessage,responseMessageStr);
}else{
return responseMessageStr;
}
}
}


最后来看看责任链模式的初始化调用:(设置了每个处理器的后继者,正是通过父类持有的引用来实现的)

@Service
public class MessageService
{
private Logger logger = Logger.getLogger(MessageService.class);

/**
*
* 功能描述:根据上行消息返回下行消息
*
* @param requestXml
* @return
* @throws StreamException
* @throws IOException
*/
public String getResponseXml(String requestXmlData) throws StreamException, IOException
{
String responseMessageStr = StringUtils.EMPTY;
BaseMessage baseMessage = XmlUtil.getBaseMessage(requestXmlData);
AbstractMessageHandler message2DBHandler = new Message2DBHandler();
AbstractMessageHandler messageStatusHandler = new MessageStatusHandler();
AbstractMessageHandler messageResponseHandler = new MessageResponseHandler();
//设置消息入库的后继操作为修改数据库状态
message2DBHandler.setSuccessor(messageStatusHandler);
//设置修改数据库状态的后继操作为返回被动响应消息
messageStatusHandler.setSuccessor(messageResponseHandler);
message2DBHandler.handleMessage(requestXmlData, baseMessage,responseMessageStr);
logger.info("responseMessageStr:"+responseMessageStr);
return responseMessageStr;
}
}


(2)工厂模式的应用

针对用户上行的不同类型的报文,我们可以用工厂模式返回不同的处理对象,这些处理对象都继承了同样的抽象类,重写了同一个接口方法,从而在具体方法中处理不同的业务逻辑。这里抽象类的作用是用来抽取公共方法,全部实现过程如下:

定义消息处理器接口:

/**
*
* @类名: IMessageProcessor.java
* @描述:处理器接口,用来处理不同的应答消息
* @作者: mxyanx
* @修改日期: 2015年3月3日
*/
public interface IMessageProcessor
{
void process(String requestXmlData, BaseMessage baseMessage,String responseMessageStr) throws IOException;
}


定义抽象类,实现处理器接口,同时定义公共方法:

/**
*
* @类名: PublicProcessor.java
* @描述:消息公共处理器,提供各种方法供具体处理器调用
* @作者: mxyanx
* @修改日期: 2015年3月5日
*/
@Component
public class PublicProcessor implements IMessageProcessor
{

public void process(String requestXmlData, BaseMessage baseMessage, String responseMessageStr) throws IOException
{
// TODO Auto-generated method stub

}

/**
*
* 功能描述:返回被动响应消息,主要有两种类型:文本类型和图文类型
*
* @return
*/
protected String getResMessageById(String messageId, BaseMessage baseMessage)
{
......
}

/**
*
* 功能描述:应答文本消息入库
*
* @param content
*/
protected void insertResTextMessage2DB(String content, BaseMessage baseMessage)
{
......
}

/**
*
* 功能描述:应答图文消息入库
*
* @param articleMessageItems
* @param baseMessage
*/
protected void insertResArticleMessage2DB(List<ArticleMessageItem> articleMessageItems, BaseMessage baseMessage)
{
......
}

/**
* click事件消息类型返回
*
* 功能描述:返回响应给用户的消息,主要有两种类型:文本类型和图文类型
*
* @return
*/
protected String getResMessageByName(String messageName, BaseMessage baseMessage)
{
......
}

/**
*
* 功能描述:判断多客服开关是否启用
* @param baseMessage
* @return
*/
protected boolean getCustomerServiceFlag(String accountId){
......
}

}


定义工厂类,根据用户上行消息的内容返回不同的处理器:

/**
*
* @类名: ProcessorFactory.java
* @描述:处理器工厂类,用来返回不同的处理器
* @作者: mxyanx
* @修改日期: 2015年3月3日
*/
public class ProcessorFactory
{
public static IMessageProcessor getProcessorMessage(String msgType)
{
if (msgType.equalsIgnoreCase("text"))
{
return new TextMessageProcessorImpl();
}
else if (msgType.equalsIgnoreCase("location"))
{
return new LocationMessageProcessorImpl();
}
else if (msgType.equalsIgnoreCase("image"))
{
return new ImageMessageProcessorImpl();
}
else if (msgType.equalsIgnoreCase("event"))
{
return new EventMessageProcessorImpl();
}
else
{
return null;
}
}

}


定义具体的处理器类之一:文本消息处理器

/**
*
* @类名: TextMessageProcessorImpl.java
* @描述:文本消息处理器,生成应答消息和应答消息入库
* @作者: mxyanx
* @修改日期: 2015年3月5日
*/
@Component
public class TextMessageProcessorImpl extends PublicProcessor
{
private static final Logger logger = Logger.getLogger(TextMessageProcessorImpl.class);

@Override
public void process(String requestXmlData, BaseMessage baseMessage, String responseMessageStr) throws IOException
{
//处理文本消息,这里可能用到抽象类中的方法
......

}

}


定义具体的处理器之二:图片消息处理器

/**
*
* @类名: ImageMessageProcessorImpl.java
* @描述:图片消息处理器,生成应答消息和应答消息入库
* @作者: mxyanx
* @修改日期: 2015年3月5日
*/
@Component
public class ImageMessageProcessorImpl extends PublicProcessor
{
private static final Logger logger = Logger.getLogger(ImageMessageProcessorImpl.class);

@Override
public void process(String requestXmlData, BaseMessage baseMessage, String responseMessageStr) throws IOException
{
//处理图片消息,这里可能用到抽象类中的方法
......

}

}


定义具体的处理器之三:地理位置消息处理器

/**
*
* @类名: LocationMessageProcessorImpl.java
* @描述:地理位置消息处理器,生成应答消息和应答消息入库
* @作者: mxyanx
* @修改日期: 2015年3月5日
*/
@Component
public class LocationMessageProcessorImpl extends PublicProcessor
{
private static final Logger logger = Logger.getLogger(ImageMessageProcessorImpl.class);

@Override
public void process(String requestXmlData, BaseMessage baseMessage, String responseMessageStr) throws IOException
{
//处理地理位置消息,这里可能用到抽象类中的方法
......

}

}


......

最后,看一下工厂模式是如何调用的:

/**
*
* @类名: MessageResponseHandler.java
* @描述:被动响应消息处理器,专门返回被动响应消息
* @作者: mxyanx
* @修改日期: 2015年3月2日
*/
@Component
public class MessageResponseHandler extends AbstractMessageHandler
{

@Override
public String handleMessage(String requestXmlData, BaseMessage baseMessage,String responseMessageStr) throws IOException
{
//使用工厂模式,根据消息类型返回不同的处理器组装返回消息
IMessageProcessor messageProcessor = ProcessorFactory.getProcessorMessage(baseMessage.getMsgType());
messageProcessor.process(requestXmlData, baseMessage, responseMessageStr);
//如果有后继处理器,则返回下一个处理器的结果
if(this.getSuccessor() != null){
return this.getSuccessor().handleMessage(requestXmlData, baseMessage,responseMessageStr);
}else{
return responseMessageStr;
}
}

}


使用上述两种设计模式,可以使得业务逻辑变得清晰,代码的层次感更强,希望上述介绍对读者有帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: