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

来源:互联网 发布:mysql e 执行sql 编辑:程序博客网 时间:2024/06/07 03:50

        在公众号建设中,发送被动响应消息是最核心的环节,用户主动发给微信的消息经微信服务器处理后,统一变成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日 */@Componentpublic 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日 */@Componentpublic 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日 */@Componentpublic 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;        }    }}

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

@Servicepublic 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日 */@Componentpublic 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日 */@Componentpublic 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日 */@Componentpublic 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日 */@Componentpublic 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日 */@Componentpublic 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;        }    }   }







使用上述两种设计模式,可以使得业务逻辑变得清晰,代码的层次感更强,希望上述介绍对读者有帮助。














0 0
原创粉丝点击