Silentdoer

导航

记一次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这些“插件”和相关的接口,因为有了这些预留的切面和对应的接口,使得模块能够动态的更新和取消功能。

posted on 2018-02-20 20:53  Silentdoer  阅读(210)  评论(0编辑  收藏  举报