零基础学Struts
上QQ阅读APP看书,第一时间看更新

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>