基于Servlet的MVC控制器框架设计
2015-05-30郑建华朱蓉邱振国
郑建华 朱蓉 邱振国
摘 要: 控制器在MVC模式中起着重要作用。分析了J2EE中MVC模式的实现方式,指出了经典的基于Servlet控制器的不足,分析了Struts2中控制器的核心原理。提出了一种基于门面模式和简单工厂模式的轻量级控制器框架,将其命名为“1+N”模式控制器。该控制器主要包括核心控制器和业务控制器,由核心控制器统一响应客户前端的请求,并将请求转换到相应的业务控制器进行处理。给出了该框架中核心类的源代码。该框架易于使用且具有较好的可扩展性和可维护性。
关键词: MVC; 控制器; 门面模式; 简单工厂模式; 核心控制器
中图分类号:TP311 文献标志码:A 文章编号:1006-8228(2015)04-43-03
Abstract: The controller plays an important role in the MVC mode, this paper analyzes the implementation of the MVC model in J2EE, poins out the drawback of the classic controller based on Servlet and analyzes the core principle of the controller in Struts2. Then proposes a framework of lightweight controller based on Facade pattern and simple factory pattern, which named as “1+N” controller. The controller framework incudes core controller and business controller. The core controller responses the client request unified and then transfers the request to the business controller to process. The paper gives the source code of the core class in the framework. The framework is easy to use and has good scalability and maintainability.
Key words: MVC; controller; facade pattern; simple factory pattern; core controller
0 引言
当前信息化水平已成为衡量一个国家现代化水平和综合国力的重要标志。信息化建设离不开系统的建设,传统的Web应用系统会在表现层包含管理用户交互的代码,这样对于整个应用系统来说,它的业务逻辑、控制逻辑和运行状态等都很难被重用。MVC模式解耦了业务逻辑、控制逻辑,提高了代码重用,又能使系统易于维护和修改[1]。
然而目前的研究更多是关注模型层和业务逻辑层,对MVC中控制器的研究较少。在目前被广泛使用的基于J2EE的Web开发方式中,控制器主要是依靠Serlvet实现,而经典的Serlvet控制器实现方式存在诸如Serlvet类过多,web.xml配置复杂等缺点。虽然Struts2.0提供了一种控制器实现方式,但是Struts2.0的复杂性对于初学者有较高难度。本研究基于门面模式和简单工厂模式提出一种轻量级的“1+N”控制器框架,并给出了核心类的关键实现代码。
1 MVC模式简介
模型(Model)-视图(View)-控制器(Controller)(MVC)[2]是Xerox PARC在八十年代为编程语言Smalltalk-80发明的一种软件设计模式,至今已被广泛使用[3]。MVC把交互系统的组成分解成模型、视图、控制器三种组件。
模型组件封装了应用程序的核心数据,以及这些数据的访问和修改的业务规则,它表达了程序所使用的数据和生成数据的运行状态,它独立于具体的界面表达和I/O操作。
视图组件把模型数据及逻辑关系和状态的信息以特定形式展示给用户,主要负责如何表示数据,对于相同的信息可以有多个不同的显示形式,并当模型改变时,维护表示的一致性。视图也负责把用户动作传递给控制器。
控制组件负责模型和视图之间的交互,控制对用户输入的响应方式和流程,确保视图与模型间的对应联系。它接受用户的输入,将输入反馈给模型,进而实现对模型的计算控制,同时又将模型的改变及时反映在视图上,使模型和视图协调。
模型、视图与控制器的分离,使得一个模型可以具有多个显示视图,模型数据发生变化,控制器都会将变化通知所有的视图,导致显示的更新,实现了数据层与表示层的分离,这使得程序开发更加灵活,并且可以减少重复性代码,实现代码重用,易于维护和修改。
2 J2EE中MVC模式实现及不足
2.1 基于JSP+Sevlet的MVC模式实现
MVC模式目前被广泛应用于Web系统开发。比如有文献研究了.Net平台下的基于MVC模式的Web应用开发[4],而在J2EE体系中,其应用也越来越广泛[5]。
J2EE中经典MVC模式采用的是基于Jsp+Servlet+JavaBean的实现,由Jsp页面实现视图(View),负责前台的展示;JavaBean实现模型(model),处理业务逻辑;由Servlet实现控制器(Controller),负责业务层和视图层的协调控制。
图1展示了在线商城系统的基于Jsp+Servlet+JavaBean的J2EE中MVC模式的实现过程,整个框架的作用过程为:①Jsp页面向Servlet发送请求;②Servlet接收到Jsp请求后向JavaBean模型发送业务请求;③然后JavaBean进行相关业务处理,将返回处理结果到Servlet;④最后由Servlet根据结果显示要求,返回到不同的展示Jsp页面。比如图1中的LoginServlet可能将结果返回到Login.jsp,Succ.jsp,Error.jsp,即一个控制器可能与多个视图关联,而视图Jsp的展示结果是与模型JavaBean保持协同一致的。
通过以上方式较好地实现了三个层次功能的解耦,易于实现代码的维护和修改。
2.2 经典Servlet的控制器实现与不足
按照MVC模式的划分,在J2EE中Controller(控制器)由Servlet完成,使MVC模式中的三部分之间耦合性降到最低,最大限度地将Web应用系统中控制与业务逻辑分开。Servlet作为整个系统架构的交通枢纽,起着调度作用,其实JSP在执行前先被编译成字节码,最终以Servlet执行码形式存在。由此可知Servlet在整个J2EE体系结构中起主要作用。
目前已有的MVC模式研究较多关注模型与视图之间的分隔,而对于控制器的关注较少。在图1所示的在线商城系统的描述中一共有4个Servlet,分别表示注册、登录、查询商品、添加商品控制器。但是这样做有很多限制:①一个servlet一般只能负责一个单一的业务逻辑,因为所有的业务逻辑通常情况下都集中在doPost这样一个方法当中,随着业务的增加,servlet数量会急剧增加;②系统每添加一个servlet就要在web.xml里面写一个servlet配置,使得web.xml的配置文件非常的繁重;③由于每个Jsp页面都对应不同的serlvet,使得在Jsp视图中容易配置出错,页面不易于维护。
3 轻量级的MVC控制器框架设计
3.1 Struts2简介与不足
控制器是MVC模式的枢纽,控制器的撰写容易程度以及使用便捷性直接影响编程人员的效率以及程序的性能。如图1所示的案例中,一个浏览器的请求对应一个Servlet控制器的方式存在如2.2小节所述的几点不足。
在J2EE体系中,Struts2[6]的出现为使用MVC模式提供了便利,Struts2是一种基于MVC的Web应用框架。Struts2有三部分组成:核心控制器(FilterDispatcher)、业务控制器和业务逻辑组件。其中核心控制器FilterDispatcher由Struts2提供,而业务逻辑控制器和业务逻辑组件由用户自己实现。业务控制器组件实现Action类的实例,而业务逻辑组件一般由javaBean或者EJB实现。Struts2的运行过程是:核心控制器FilterDispatcher会过滤所有的请求,如果请求以 action结尾,该请求会转入框架处理。当框架获取action请求后,根据action的前半部分决定调用哪个业务逻辑组件。最后根据业务逻辑组件的处理信息决定转发到哪个视图。Struts2实现MVC模式,结构清晰,使开发者只关注业务逻辑的实现。此外Struts有丰富的标记库(Taglib),如能灵活动用,能大大提高开发效率。但是,Struts的使用仍是一个复杂的过程,首先是对Struts-config.xml的管理;其次是转到视图时,需要配置forward,如果有十个展示层的Jsp,需要配置十次struts,而且还不包括有时候目录/文件变更,需要重新修改forward;再就是每次修改配置之后,要求重新部署整个项目,而tomcate服务器还必须重新启动。虽然Taglib内容丰富,但是要想灵活运用它却需要一个长期的过程,因此对于初学者而言直接采用Struts有较高难度。
3.2 1+N模式控制器框架设计
Struts2对于初学者而言使用过程比较复杂,但是Struts2提供了一个很好的策略,即将控制器区分为核心控制器和业务控制器,这是一种值得借鉴的设计模式。
根据GOF23设计模式中的门面模式(Fa?ade pattern)[7]定义:为子系统中的一组接口提供一个一致的界面。Fa?ade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。在一定程度上Stuts2的核心控制器FilterDispatcher即为采用该设计模式的理念,这种理念使得外部调用者并不知道底层的实现细节,由Fa?ade来进行转发。如图2所示。
基于以上分析,本文基于门面模式和简单工厂模式设计了一种“1+N模式”轻量级控制器框架,“1+N”中的“1”表示核心控制器,核心控制器即为门面模式中的Fa?ade,其作用主要是响应来自客户端的请求,并根据请求转向到具体的业务控制器,从而完成该次请求的过程,最后通过业务控制器返回的JSP 视图地址,完成重定向。而各个业务控制器使用JavaBean技术来实现,其主要作用是管理请求流程处理过程,实现模型和视图二者关系的映射,实际的业务处理过程还是由模型实现。图3中的“1+N模式控制器”即表示了以上的核心思想。
图3中的CoreServlet即为核心控制器,BusinessServletImp1即为业务控制器,在每次请求过程中都是由CoreServlet响应来自JspClient的请求,并根据请求的参数转换为响应的业务控制器来进行处理。以上的处理方式借鉴了Fa?ade设计模式,但是又不完全一样。在Fa?ade模式中客户端不需要知道到底需要调用什么样的内部模块,但是在本框架中,客户端需要通过参数告知核心控制器其业务控制器的类型和名字。
如图3所示,本文设计的“1+N”模式控制器在实现调整的过程中还采用了简单工厂模式[7]实现,从设计模式的类型上,简单工厂模式是属于创建型模式,又称作静态工厂方法(Static Factory Method)模式,简单工厂模式的核心思路是由一个工厂对象决定创建出哪一种产品类的实例。如图4可以看出,“1+N”模式控制器涵盖了三种类:一是工厂类,即BusinessServletFactory,二是产品接口IBusinessServlet,三是具体的产品,即BusinessServletImp。其中,工厂类BusinessServletFactory负责整个创建产品的逻辑判断,为了使工厂类能够知道需要哪一种产品,需要在创建产品时传递给工厂类一个参数,而这个参数可以从客户端的请求中获取,从而确定想要创建哪种产品。通过简单工厂模式的使用,避免了在核心控制器中不断采用逻辑判断的方式来确定所需要的业务控制器的编程方式。
3.3 1+N模式控制器各类核心代码示例
⑴ JspClient请求代码设计
根据3.2小节的分析,在JSP页面中,只需要指定核心控制器路径以及业务控制器名称即可,比如一个登陆的Jsp中form的action可以编写action ="CoreServlet ? BusinessServlet= LoginBusinessServletImp。上面的源码中,指定了要处理的控制器为CoreServlet,并且通过参数指定了业务控制器的名称为LoginBusinessServletImp。
⑵ CoreServlet处理流程核心代码设计
根据3.2小节的分析,CoreServlet的工作主要是响应Jsp的请求,然后通过工厂类获取相应的业务控制器对象,最后通过业务控制器返回的JSP视图地址,完成重定向。关键代码示例如下。
通过上述分析可以发现:1+N”模式控制器是一种轻量级框架,其方法原理清晰,使用简单,避免了Struts中复杂的配置文件;由于采用了门面模式的核心思想,降低客户端请求配置的难度,只需要指定核心控制器的路径及辅助业务控制器名字即可,同时也避免了需要在系统的web.xml中配置大量servlet的麻烦;由于采用了简单工厂模式,使得业务控制器的生成不需要复杂的流程判断,而且模型和视图的修改不会影响到核心控制器的修改,使得核心控制器具有较好的可维护性。
4 结束语
MVC模式已经被广泛应用在各种Web系统开发中,本文对J2EE中MVC模式的控制器的实现做了进一步研究,基于门面模式和简单工厂模式设计了“1+N”模式控制器框架,即通过核心控制器和业务控制器联合实现控制器的功能, 核心控制器负责统一响应客户端的请求,并通过工厂类得到业务控制器对象,然后将客户端请求转换到业务控制器进行处理。该框架简化了web.xml配置,降低了客户端请求配置的难度,框架采用简单工厂模式,具有较好的可扩展性和可维护性。目前该框架已应用在罗定市特色农产品网络信息服务平台中,取得了较好效果。
参考文献:
[1] 王文新.基于模型-视图-控制器的Web应用程序框架设计[J].信息与电子工程,2009.7(4):358-360
[2] 郑建华,陈尔晓.MVCA模式设计及应用研究[J].电脑知识与技术,2012.32(1):199-200,225
[3] E. Hanyuda.MVC dance: Connecting software development andcorporeality from agile process and pattern language perspectives[A].Proceedings of Second International Conference on Creating,Connecting and Collaborating through Computing[C].Kyoto University, Kyoto, Japan,2004:174-180
[4] 龚薇华,王晨光,俞欢军.基于MVC模式和.NET的公司内部管理信息系统设计[J].计算机工程与设计,2007.28(9):2142-2144
[5] 张丽虹.基于J2EE架构的经济普查系统设计与实现[J].计算机时代,2013.2:28-31
[6] 李倩倩.基于Struts+Spring+Hibernate框架的编目管理系统的研究与实现[D].中国地质大学(北京)硕士论文,2013.
[7] 刘德山,金百东.Java设计模式深入研究[M].人民邮电出版社,2014.