1.2 MVC框架介绍
MVC框架是一些组织或企业基于MVC设计模式而开发出来的。目前比较流行的MVC框架有Struts 1、Struts 2及WebWork。这些框架除了很好地实现了MVC,还提供了大量的类库供开发使用。
1.2.1 常用的MVC框架
下面来了解为什么要使用MVC框架。以前面编写那个小项目为例,通过创建一个Servlet来接受用户的参数,并通过调用业务逻辑组件来进行判断。这样的MVC设计肯定是可以的,但是随着软件行业的发展,许多组织以及企业发开出了基于MVC设计模式的MVC框架。开发人员不必自己来实现MVC设计模式,只需基于这类MVC框架之上进行开发。这些框架提供的功能可以减少开发人员的开发难度,增加开发效率,更重要的是这类框架提供了一种MVC设计的标准。以前大家肯定也学过MFC, MFC就是微软的核心类库,在开发程序时,用户可以完全基于MFC这个类库来进行开发,而不是完全自己去编写每一个类。MVC框架已经实现好了MVC设计模式,只用在其上来开发就可以了。
目前常用的MVC框架非常多,其中广泛应用的有Struts、WebWork,还有最新的Struts21-5等。下面来介绍一下Struts 1框架。
1.2.2 Struts 1框架简介
Struts 1于2001年6月发布,是第一个发布的MVC框架。从发布至今一直深受广大开发人员的拥护。其所拥有的开发人群也是其他MVC无法比拟的。
Struts 1通过核心控制器Action Servlet来接受用户所有的请求,并将请求转发给业务逻辑控制器。由业务逻辑控制器处理用户请求,用户请求处理完成后,业务逻辑控制器会根据业务逻辑将处理结果通过JSP的方式返回给用户。
控制器是Struts 1的核心部分,包括核心控制器ActionServlet和业务逻辑控制器。其中ActionServlet由Struts 1框架提供,而业务逻辑控制器由开发人员根据特定的业务逻辑提供。下面是一个简单的基于Struts 1开发的登录案例流程图,如图1.9所示。
图1.9 登录案例程序执行流程
其中LoginAction为业务逻辑控制器,也就是由开发人员自行创建的。LoginForm是一个ActionForm, ActionForm用来封装用户的请求参数。ActionForm是一个普通的Java对象,它需要为用户提交的每一个参数提供一个对应的属性,并为每个属性提供setter和getter方法。ActionForward可以理解为一个逻辑视图名。
还有一个非常重要的文件就是Struts-config.xml配置文件,在该配置文件中可以配置业务逻辑控制器Action以及相应的ActionForm。逻辑视图名和视图资源之间的对应关系也是在该文件中定义。
1.2.3 下载并安装Struts 1框架
Struts框架是由Apache开源组织开发并负责维护的,可以直接打开Struts的官方站点,这里只需要下载Struts框架,因此可以直接打开Apache的官方下载站点“http://people.apache.org/dist”,如图1.10所示。
在该页面里列出了所有Apache负责的项目。单击其中的“struts”链接,页面跳转到Struts框架下载页,如图1.11所示。
图1.10 Apache官方下载站点
图1.11 Struts框架下载页
这里选择Struts 1.2.9版本,所以单击“v1.2.9”链接,跳转到Struts 1的1.2.9版本下载页,如图1.12所示。
该页面中包含了许多的下载链接,大致归类为3类:一类是“struts-1.2.9-src”,包含Struts框架的源代码;一类是“struts-1.2.9-bin”,包含编译后的文件;一类是“struts-1.2.9-lib”,包含的库文件,这些库文件在“struts-1.2.9-bin”中已经包含了。
其中gz是Linux、UNIX系统下的一种包格式,类似于Windows下的压缩文件(如rar、zip)。这里单击“struts-1.2.9-bin.zip”链接进行下载。下载完成后,解压该文件,该文件结构如图1.13所示。
图1.12 Struts 1.2.9版本下载页
图1.13 文件结构
下面简要介绍一下“struts-1.2.9-bin.zip”结构中的常用项。
❑ contrib:该文件夹中存放Struts 1表达式支持的类库以及标签库文件。
❑ lib:该文件夹中存放Struts 1框架的核心类库。
❑ webapps:该文件夹中存放Struts 1框架的示例程序以及文档。
下面介绍如何在项目中安装Struts 1框架。
安装步骤如下。
(1)新建一个项目,将lib目录下的全部jar文件复制到项目中的WEB-INF/lib下。
(2)将lib目录下的全部TLD文件复制到WEB-INF下。
(3)将“validator-rules.xml”文件复制到WEB-INF下。
(4)如果需要使用EL表达式语言,就必须将contrib下的jar文件复制到WEB-INF/lib下。
(5)在编译程序时,还必须将“struts.jar”文件增加到classpath环境变量中。
Struts 1框架已经安装好了,下面通过Struts 1框架来改进以前那个登录案例。
1.2.4 基于Struts 1框架实现登录案例
其实使用Struts 1框架实现登录案例非常简单,将当时使用MVC设计模式改进后的代码稍微修改,并增加一些Struts 1特有的配置和特性即可。下面来演示如何通过Struts 1框架来实现这个登录案例。
步骤如下。
(1)新建Web项目,并通过上小节介绍的步骤安装Struts 1框架。
(2)将前一项目中的“login.jsp”和“login_success.jsp”以及“login_failure.jsp”复制到项目中。
(3)配置“web.xml”文件,在该文件中配置Struts 1的核心控制器的名称,配置Struts 1的核心控制器的实现类,配置Struts 1的初始化信息以及配置ActionServlet接受所有以“.do”结尾的请求,修改代码如下。
<? xml version="1.0" encoding="UTF-8"? > <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <! --配置Struts 1的核心控制器的名称--> <servlet-name>action</servlet-name> <! --配置Struts 1的核心控制器的实现类--> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <! --配置Struts 1的初始化信息--> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <! --配置ActionServlet接受所有以".do"结尾的请求--> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
注意
如果xml文件中使用中文(包括注释),那么在xml中encoding必须定义为“gb2312”,或者使用“utf-8”的编码格式来保存该文件。如使用EditPlus编写该xml,则在保存文件时使用“utf-8”的编码保存文件,如图1.14所示。
图1.14 设定文件编码格式
(4)新建ActionForm,该ActionForm类名为LoginForm。LoginForm用来封装用户请求的参数,根据表单中的两个参数“uname”和“upassword”,在LoginForm中必须定义setUname和setUPassword这两个方法。Struts 1框架底层是通过这两个方法将参数值设置到LoginForm的属性上的,而不是通过LoginForm的属性来设置值的。不过,一般情况下ActionForm中的属性名称还是定义为和用户请求表单中的参数名相同,以便管理。
LoginForm中要为属性添加setter和getter方法,但是它不是POJO(Plain Old Java Objects,普通Java对象)。它必须继承Struts 1的ActionForm基类。LoginForm代码如下。
package net.hncu.struts.form; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; public class LoginForm extends ActionForm { private String uname; private String upassword; //获得uname值 public String getUname() { return uname; } //设置uname值 public void setUname(String uname) { this.uname = uname; } //获得password值 public String getUpassword() { return upassword; } //设置password值 public void setUpassword(String upassword) { this.upassword = upassword; } }
(5)修改业务逻辑组件LoginCheck类,为该类定义包名,添加代码如下所示。
package net.hncu. service;
(6)新建业务逻辑控制器Action,类名为LoginAction。LoginAction继承Action,并包含一个execute方法。在该方法中获得ActionForm的实例,其中封装了用户请求的参数。并调用业务逻辑组件处理登录请求,根据返回结果调用不同的页面来显示登录结果。LoginAction代码如下所示。
package net.hncu.struts.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.hncu.service.LoginCheck; import net.hncu.struts.form.LoginForm; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; public class LoginAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { //获得ActionForm的实例,其中封装了用户请求的参数 LoginForm loginForm = (LoginForm)form; //取得用户请求的参数 String name = loginForm.getUname(); String password = loginForm.getUpassword(); //new一个LoginCheck对象 LoginCheck lc = new LoginCheck(); //调用业务逻辑组件的判断功能来判断 if(lc.isLogin(name, password)){ //如果为合法用户,在request范围中添加属性login,其属性值为true,并设定跳转的逻辑 视图为"success"的页面 request.setAttribute("login", "true"); return mapping.findForward("success"); }else{ //并设定跳转的逻辑视图为"failure"的页面 return mapping.findForward("failure"); } }
(7)编译业务逻辑控制器LoginAction、LoginForm以及业务逻辑组件LoginCheck。并将编译后的class文件(包括完整的包名)放入项目的WEB-INF文件夹下的classes文件夹中。
(8)在Web项目的WEB-INF目录下新建“struts-config.xml”文件,该文件用来配置Action、ActionForm以及逻辑视图和视图资源之间的映射关系。“struts-config.xml”代码如下所示。
<? xml version="1.0" encoding="UTF-8"? > <! DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd"> <! --Struts 1配置文件的根元素--> <struts-config> <! --配置ActionForm,所有ActionFrom都必须定义在form-beans元素中--> <form-beans > <! --通过form-bean元素定义ActionForm,其中name属性指定ActionForm的名称, type属性指定ActionForm的实现类--> <form-bean name="loginForm" type="net.hncu.struts.form.LoginForm" /> </form-beans> <! --配置Action,所有Action都必须定义在action-mapping元素中--> <action-mappings > <! --通过action元素定义Action,其中path属性指定处理的URL, type属性用来指定Action的实现类, name属性用来指定对应的ActionForm的名称,scope属性用来指定ActionForm存放的属性范围--> <action path="/login" type="net.hncu.struts.action.LoginAction" name="loginForm" scope="request" > <! --定义逻辑视图success,对应的jsp页面为"login_success.jsp"--> <forward name="success" path="/login_success.jsp"></forward> <! --定义逻辑视图failure,对应的jsp页面为login_failure.jsp--> <forward name="failure" path="/login_failure.jsp"></forward> </action> </action-mappings> </struts-config>
(9)修改“login.jsp”,修改页面提交页,使页面提交到“login.do”。
<form action="login.do" method="post">
(10)部署该项目。打开Tomcat安装目录下的conf文件夹下的“server.xml”文件。在文件的最下面的“</host>”标签之前添加如下代码。
<Context path="/03"docBase="E:\BookDemo\ch01\03"reloadable="true"crossContext="true"> </Context>