第1章 认识Struts 2
本章要点
掌握MVC架构模式
理解Web框架是什么
弄清楚Struts 1、Struts 2和WebWork三者之间的关系
搭建本书的开发环境
Struts 2已��推出了稳定的版本,其先进的架构和设计思想,随着时间的推移,相信会有越来越多的人开始使用Struts 2。基于Struts原有的人气,加上采用了WebWork的设计架构,Struts 2必将成为*为流行的Web开发框架之一。
1.1 什么是Web框架
随着Internet的发展,基于HTTP协议和HTML标准的Web应用呈几何数量级增长,人们在不知不觉中已经被网络悄悄地改变了生活。在网络普及之前,我们购买图书要去书店,给亲人汇钱要去邮局或者银行,而现在,一切都是这么便捷,你可以在网上购买图书、汇款、缴纳电话费,你甚者可以为远在他乡的女朋友订购一束玫瑰。各种各样的网上业务丰富了我们的生活,节省了我们的时间,提高了我们的工作效率,改善了我们的生活品质。
支撑这些网上业务的就是各种各样的Web应用,而这些Web应用又是用各种Web技术开发的。早期的Web应用主要是静态页面的浏览(如新闻的浏览),这些静态页面使用HTML语言来编写。随着网络的发展,很多线下业务开始向网上发展,基于Internet的Web应用也变得越来越复杂,不但要和数据库交互,而且还要和用户进行交互,由此衍生出了各种服务器端页面编写技术,目前应用得较多的三种服务器端页面编写技术就是ASP、JSP和PHP。
JSP通过在HTML页面文件中嵌入Java脚本代码,从而实现动态网页功能。HTML标签负责页面的布局和显示外观,Java代码负责提取动态数据,实现业务逻辑。对于简单的应用,采用这种方式可以简化开发难度,加快开发进度;然而,对于一些较大的应用,大量的HTML和Java代码的混杂导致了页面的显示逻辑和业务逻辑交错在一起,使得代码的可读性变差,维护难度增加,不利于HTML编辑人员和Java开发人员的分工协作。
为了分离页面的表现逻辑和业务逻辑,使程序各部分的职责更加清晰,增强代码的可维护性,SUN公司在JSP的早期规范中制定了两种JSP开发模型,分别为模型1(Model 1)和模型2(Model 2)。
1.1.1 模型1
模型1使用JSP+JavaBeans技术将页面显示和业务逻辑处理分开。JSP实现页面的显示,JavaBean对象用来承载数据和实现业务逻辑。模型1的结构如图1-1所示。
图1-1 模型1的JSP架构
在模型1中,JSP页面独自响应请求并将处理结果返回给客户,所有的数据通过JavaBean来处理,JSP实现页面的显示。
我们看一个按照模型1的结构实现的用户登录的例子。在这个例子中有两个JavaBean类,UserBean和UserCheckBean,UserBean对象负责保存用户数据,UserCheckBean对象负责实现对用户登录信息进行验证的业务逻辑。
UserBean的代码片段如例1-1所示。
例1-1 UserBean.java
通过这个例子可以看到,模型1将页面显示和业务逻辑进行了分离,不足之处是在JSP页面中仍然需要编写流程控制和调用JavaBean的代码,当需要处理的业务逻辑非常复杂时,这种情况会变得更加糟糕。在JSP页面中嵌入过多的Java代码将会使程序变得异常复杂,对于前端页面设计人员来说,大量的嵌入代码使他们无从下手。
模型1不能满足大型应用的需要,但是对于小型应用,由于该模型简单,且不涉及过多的要素,可以很好地满足小型应用的需要。所以在简单应用中,应该优先考虑模型1。
1.1.2 模型2和MVC
在模型1中,JSP页面嵌入了流程控制代码和部分的逻辑处理代码,我们可以将这部分代码提取出来,放到一个单独的角色中,这个角色就是控制器角色,而这样的Web架构就是模型2了。模型2符合MVC架构模式,MVC即模型-视图-控制器(Model-View-Controller)。
MVC架构有助于将应用程序分割成若干逻辑部件,使程序设计变得更加容易。MVC架构提供了一种按功能对各种对象进行分割的方法(这些对象是用来维护和表现数据的),其目的是为了将各对象间的耦合程度降至*低。MVC架构原本是为了将传统的输入(input)、处理(processing)和输出(output)任务运用到图形化用户交互模型中而设计的,但是,将这些概念运用到基于Web的企业级多层应用领域也是很适合的。
在MVC架构中,一个应用被分成三个部分:模型(Model)、视图(View)和控制器(Controller)。
模型代表应用程序的数据以及用于访问控制和修改这些数据的业务规则。当模型发生改变时,它会通知视图,并为视图提供查询模型相关状态的能力。同时,它也为控制器提供访问封装在模型内部的应用程序功能的能力。
视图用来组织模型的内容。它从模型那里获得数据并指定这些数据如何表现。当模型变化时,视图负责维护数据表现的一致性。视图同时将用户的请求通知控制器。
控制器定义了应用程序的行为。它负责对来自视图的用户请求进行解释,并把这些请求映射成相应的行为,这些行为由模型负责实现。在独立运行的GUI客户端,用户的请求可能是一些鼠标单击或是菜单选择操作。在一个Web应用程序中,它们的表现形式可能是一些来自客户端的GET或POST的HTTP请求。模型所实现的行为包括处理业务和修改模型的状态。根据用户请求和模型行为的结果,控制器选择一个视图作为对用户请求的响应。图1-2描述了在MVC应用程序中模型、视图、控制器三部分的关系。
在JSP模型2中,控制器的角色由Servlet来实现,视图的角色由JSP页面来实现,模型的角色由JavaBean来实现。模型2的架构如图1-3所示。
Servlet充当控制器的角色,它接受请求,并且根据请求信息将它们分发给相应的JSP页面来产生响应。Servlet控制器还根据JSP视图的需求生成JavaBean的实例并输出给JSP环境。JSP视图可以通过直接调用JavaBean实例的方法或使用和动作元素来得到JavaBean中的数据。
下面我们按照模型2的架构重写用户登录验证的程序。在本例中,两个JavaBean类(UserBean和UserCheckBean)和welcome.jsp仍然用模型1例子中的程序,主要增加作为控制器使用的Servlet。
在模型2的login.jsp中,我们增加了一个隐藏输入域,如下:
服务器端的控制器可以根据这个隐藏字段的值来判断用户是请求登录表单,还是提交登录信息。
ControllerServlet类充当控制器,它接收用户的请求,根据请求的不同进行相应的处理,并选择对应的视图呈现给用户。例如,当用户提交登录表单时,ControllerServlet实例化UserBean对象保存用户登录信息,实例化UserCheckBean对象对用户登录信息进行验证,并根据登录成功与否选择欢迎或者失败页面呈现给用户。ControllerServlet类的代码如例1-6所示。
完整的代码请参看本书配套光盘中的ch01目录,测试时,输入URL:
http://localhost:8080/ch01/model2/login
本例中的JSP页面不包含任何的流程控制和业务处理逻辑,它只是简单地检索控制器创建的JavaBean对象,然后动态内容插入到预定义的页面模板中。
采用模型2的架构,可以将页面的显示、业务逻辑的处理和流程的控制很清晰地区分开,JSP负责数据的显示,JavaBean负责承载数据以及业务逻辑的处理,Servlet负责流程的控制。采用模型2架构的Web应用程序很容易维护和扩展,因为作为视图的JSP页面之间没有直接的关联。另外,在大型项目的开发过程中,采用模型2的架构,可以充分利用前端页面设计人员和后端Java开发人员所掌握的不同技能,页面设计人员可以发挥自己的美术和设计才能来表现页面,程序开发人员可以发挥自己擅长逻辑思维的特点,实现项目中的业务逻辑处理。
在项目中,采用哪种模型要根据实际的业务需求来确定。一般来说,对于小型的、业务逻辑处理不多的应用,采用模型1比较合适。如果应用有着较复杂的逻辑,并且返回的视图也不同,那么采用模型2较为合适。
1.1.3 Web框架的诞生
基于MVC架构模式开发的Web应用程序,容易出现多个控制器,在编写控制器时,对于页面导航的处理也会比较复杂。通过对基于MVC架构的Web应用程序进行分析,可以发现一些实现上的相同之处和不同之处。相同之处就是MVC架构的调用流程:
(1)所有的请求直接访问控制器,由控制器对请求进行分发;
(2)控制器实例化JavaBean对象,由JavaBean对象处理业务逻辑,以及承载数据;
(3)控制器根据请求处理的结果,向用户呈现相应的视图。
不同之处是:
(1)用户请求URL的不同对应了不同的处理单元;
(2)不同表单提交的数据需要不同的JavaBean对象来保存数据;
(3)请求处理结果的不同导致控制器向用户呈现视图的不同。
根据这些相同和不同之处,我们可以开发这样一种Web软件,它按照MVC架构实现整个调用流程,对于需要变化的地方(即上述的不同之处),采用外部配置文件的方式来解决,一种可行的配置文件如例1-7所示。
例1-7 配置文件的一种实现(采用XML文件格式)
……