• 记一次web服务模块开发过程


    一、前言

      之前在分析WCS系统的过程中,也赶上要开发其中的一个模块,用于和AGV系统对接完成一些取货、配盘等任务;在这里将这次模块开发的全过程记录一下,以便自己以后开发时能够更加快速的明白流程。

    二、需求

      当时的需求是在WMS的系统之上创建一个独立的servlet来专门负责AGV的服务模块以及客户模块;其流程大概是我方AGV服务端在启动后定期从数据库读取来自MES系统推送的组盘信息,然后根据业务调出其中可以下发的任务,通过AGV服务的接口将请求下发给AGV服务;AGV服务完成任务后会调用我方提供的接口通知我们,最后协商后的流程如大致如下(商业原因,名称均已修改):

     

    还有另一个区的更复杂的流程图,要改很多东西就不放了。

    三、代码实现

      代码实现上是模仿Struts1,通过一个抽象的AbstractManager类,以模板方法模式和命令模式构建一个框架,每个Manager都实现这个抽象的Manager;

    然后通过dom4j来动态的配置需要生效的Manager,如配置

    <services>
       <service name="/manager1" class="com.wxzd.wms.agv.server.XXManager" method="GET" />
        <service name="/manager2" class="com.wxzd.wms.agv.server.YYManager" method="POST" />
    </services>

    其中每个service都是一个实现了AbstractManager的子类,然后name表示相对于context路径的一级子路径,而class则是对应的命令对象;method则表示此manager支持

    哪些类型的HTTP请求;

    其中AbstractManager的实现方式为:

    public abstract class AbstractManager
    {
        private String serviceName;
        private String method;
        
        public String getServiceName()
        {
            return serviceName;
        }
    
        public void setServiceName(String serviceName)
        {
            this.serviceName = serviceName;
        }
    
        public String getMethod()
        {
            return method;
        }
    
        public void setMethod(String method)
        {
            this.method = method;
        }
    
        public void doManager(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
            long startTime = System.currentTimeMillis();
            handleRequest(request, response);
            long elapsedTime = System.currentTimeMillis();
            // TODO log elapsedTime
        }
        
        protected abstract void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
    }

    子类只需要实现handleRequest方法即可。然后子类里可以通过实现Resolver接口来细分对应的请求由哪个resolver来处理,在接口RequestResolver里提供support和resolve两个方法;这一步如果直接在handleRequest方法里用if判断实际上也是可以的,但是基于单一职责原则,Manager只负责去匹配符合要求的服务类,而具体由哪个方法处理则应该继续分层。

    servlet的init方法实现:初始化时将配置文件的service构造出键值对,并存入map;然后有请求来了以后取出context下的一级路径,然后和map的key匹配,匹配成功则调用此manager的handleRequest进行处理;

    四、服务端的处理流程图

     

    五:总结

    当时实现这个模块的时候还没看springmvc源码,现在再回过头来看,虽然实现了一定程度的插件式的开发,但粒度还是太大了,而且在数据处理方面

    也没有提供切面来实现更深层次的解耦;如果再次实现的话其实可以直接模仿springmvc,提供handlermapping,handleradapter,handlermethodargumentresolver,handlermethodreturnvaluehandler,httpmessageconverter这些“插件”和相关的接口,因为有了这些预留的切面和对应的接口,使得模块能够动态的更新和取消功能。

  • 相关阅读:
    踏实每一个脚印——2019年12月复盘
    修改博客园markdown编辑器代码高亮风格的方法
    Hyperion: Building the Largest In memory Search Tree
    C++11——智能指针
    拷贝控制
    分布式系统常见概念
    extern和static使用
    APUE—UNIX文件系统
    C++的一些细节
    fork和僵尸进程
  • 原文地址:https://www.cnblogs.com/silentdoer/p/8455796.html
Copyright © 2020-2023  润新知