前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[ SSH框架 ] Struts2框架学习之一

[ SSH框架 ] Struts2框架学习之一

作者头像
Kevin_Zhang
发布2018-05-22 17:05:02
8180
发布2018-05-22 17:05:02
举报
文章被收录于专栏:Kevin-ZhangCGKevin-ZhangCG

一、Struts2框架的概述

  Struts2是一种基于MVC模式的轻量级Web框架,它自问世以来,就受到了广大Web开发者的关注,并广泛应用于各种企业系统的开发中。目前掌握 Struts2框架几乎成为Wcb开发者的必备技能之一。

  接下来将针对 Struts2的特点、安装以及执行流程等内容进行详细的讲解。

1.1 什么是Struts2

  在介绍 Struts2之前,先来认识一下 Struts1。Struts1是最早的基于MVC模式的轻量级Web框架,它能够合理的划分代码结构,并包含验证框架、国际化框架等多种实用工具框架。但是随着技术的进步,Struts1的局限性也越来越多的暴露出来。为了符合更加灵活、高效的开发需求,Struts2框架应运而生。   Struts2是 Struts1的下一代产品,是在 Struts1和 WebWork技术的基础上进行合并后的全新框架( WebWork是由 OpenSymphony组织开发的,致力力于组件化和代码重用的J2 EE Web框架,它也是一个MVC框架)。虽然 Struts2的名字与 Struts1相似,但其设计思想却有很大不同。实质上,Struts2是以 WebWork为核心的,它采用拦截器的机制来处理用户的请求。这样的设计也使得业务逻辑控制器能够与 ServletAPI完全脱离开,所以 Struts2可以理解为 WebWork的更新产品。 Struts2拥有优良的设计和功能,其优势具体如下:   ●  项目开源,使用及拓展方便,天生优势。   ●  提供 Exception处理机制。   ●  Result方式的页面导航,通过 Result标签很方便的实现重定向和页面跳转。   ●  通过简单、集中的配置来调度业务类,使得配置和修改都非常容易。   ●  提供简单、统一的表达式语言来访问所有可供访问的数据。   ●  提供标准、强大的验证框架和国际化框架。   ●  提提供强大的、可以有效减少页面代码的标签。   ●  提供良好的Ajax支持。   ●  拥有简单的插件,只需放入相应的JAR包,任何人都可以扩展 Struts2框架,比如自定义拦截器。   ●  自定义结果类型、自定义标签等,为 Struts2定制制需要的功能,不需要什么特殊配置,并且可以发布给其他人使用。   ●  拥有智能的默认设置,不需要另外进行繁琐的设置。使用默认设置就可以完成大多数项目程序开发所需要的功能。   上面列举的就是 Struts2的一系列技术优势,只需对它们简单了解即可,在学习了后面的知识后,会慢慢对这些技术优势有更好的理解和体会。   那么除了 Struts2之外,还有那些优秀的WEB层框架呢?

1.2 常见的WEB层框架

  ●  Struts2

  ●  Struts1

  ●  WebWork

  ●  SpringMVC

  WEB层框架都有一个特点:基于前端控制器模式实现。

1.3 WEB层框架都会基于前端控制器的模式

  什么是前端控制器模式呢?我们来看下图,在图中传统方式的开发,有一次请求就会对应一个Servlet。这样会导致出现很多 Servlet。而 Struts2将所有的请求都先经过一个前端控制器,在前端控制器中实现框架的部分功能,剩下具体操作要提交到具体的 Action中。那么所有的请求都会经过前端控制器,那用什么来实现前端控制器呢?过滤器就是最好的一个实现方式,因为需要所有的请求都可以被过滤器拦截,然后在过滤器中实现部分的功能。所以 Struts2的前端控制器也是有过滤器来实现的。

  了解了这些之后,让我们通过一个Struts2的快速入门,来感受一下Struts2。

二、Struts2快速入门

2.1 下载Struts2的开发包:

百度网盘链接:https://pan.baidu.com/s/1HeQLGcDaXdskUayFI-vGWw   密码:qyxp

2.2 解压Struts2的开发包

解压后的目录结构如下图:

从图中可以看出,展示的是解压后的 Struts2.3.24 的目录结构,为了让大家对每个目录的内容和作用有一定的了解,接下来针对这些目录进行简单介绍,具体如下:   ●  apps:该文件夹存用于存放官方提供的 Struts2示例程序,这些程序可以作为学习者的学习资料,可为学习者提供很好的参照。各示例均为war文件,可以通过zip方式进行解压。   ●  docs:该文件夹用于存放官方提供的 Struts2文档,包括 Struts2的快速入门、 Struts2的文档,以及API文档等内容   ●  lib:该文件夹用于存放 Struts2的核心类库,以及 Struts2的第三方插件类库。

●  src:该文件夹用于存放该版本 Struts2框架对应的源代码 有了 Struts2的开发环境,接下来我们亻可以进行 Struts2的开发了。

2.3 创建一个web工程引入jar包

  首先,需要我们创建一个WEB工程,引入相关的jar包文件。引入哪些jar包呢?将 struts-2.3.24框架目录中的lib文件夹打开,得到 Struts2开发中可能用到的所有JAR包(此版本有107个JAR包)。实际的开发中,我们们根本不用引入这么多的jar包。因此要进行 struts2的基本的开发,可以参考 struts-2.3.24中的aps下的一些示例代码,其中 struts2-blank.war 是一个 struts2的空的工程。我们只需要将 struts2-blank.war 解压后进入到WEB-INF下的的lib中査看。 如下图:

  以上这些就是struts2基本的开发包了,那么这些包都有什么含义呢?说明如下图:

  从表可以看出,此版本的 Struts2项目所依赖的基础JAR包共13个。 Struts2根据据版本的不同所依赖的基础JAR包可能不完全相同,不过基本上变化不大,读者可以视情况而定。   需要注意的是,通通常使用 Struts2的Web项目并不需要利用到 Struts2的全部JAR包,因此没有必要一次将 Struts2的ib目录下的全部JAR包复制到Web项目的WEB-INF/ib路径下,而是根据需要,再添加加相应的JAR包。   那么 Struts2的基本jar包已经引入完成了,我们使用用 Struts2都是是从页面发起请求到服务器,再由服务器处理请求,响应到页面的这个过程。接下来我们就从页面开发进行 Struts2的开发吧。

2.4 创建一个页面,放置一个连接

 首先在WebContent下创建一个jsp文件,在jsp文件中编写一个Action的访问路径。如下图

代码语言:javascript
复制
    <<h1>Struts2的入门案例</h1>
    <a herf="${pageContext.request.contextPath }/HelloAction.action">访问Struts2的Action</a> 

2.5 编写一个Action

  在src下创建一个包 com.Kevin.action,在该包下新建一个 HelloAction 的类。在这个类中编写一个公有的,返回值为 String类型的方法,这个方法的名称叫做 execute,且该方法没有任何参数。(因为这个方法最终要被反射执行) 如下图:

代码语言:javascript
复制
package com.Kevin.action;

public class HelloAction {
    
    /**
     * 提供一个默认的执行的方法:execute
     * @return
     */
    public String execute(){
        System.out.println("HelloAction中的execute方法执行了------");
        return null;
    }
}

  Action类编写好了以后,Struts2框架是如何识别它就是一个Action呢,我们需要对Action类进行配置。

2.6 完成Action配置

   这个时候,我们还需要观察apps中的示例代码,在WEB-INF的 classes中,有一个名称为 struts.xml 的文件,这个文件就是 struts2的配置文件。

  我们在开发中需要将 struts xml文件引入到工程的src下,因为src下内内容发布到web服务器中就是WEB-INF下的 classes中。将 struts.xml中的原有的内容删除掉,然后配置上自己编写的 Action类就可以了。

  配置内容如下:里面的具体的标签,会在后面的地方详细介绍。

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
    
<struts>
    <package name="hellodemo" extends="struts-default" namespace="/">
        <!-- name:访问名称 class:action位置 -->
        <action name="HelloAction" class="com.Kevin.action.HelloAction">

        </action>
    </package>

</struts>    

   Action类已经配置好了,配置好了以后大家考虑一下,现在是否可以执行呢?其实现在还不行,因为之前我们介绍过,WEB层的框架都有一个特点就是基于前端控制器的模式,这个前端控制器是由过滤器实现的,所所以我们需要配置 Struts2的核心过滤器。这个过滤器的名称称是 StrutsPrepareAndExecuteFilter 。

2.7 配置核心过滤器

  Struts2框架要想执行,所有的请求都需要经过这个前端控制器(核心过滤器),所以需要配置这个核心过滤器。因为这个过滤器完成了框架的部分的功能。那么我们接下来对过滤器进行配置。我们打开web.xml,在web.xml中进行如下配置。

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

  那么到这,我们程序就可以执行了,但是到了 Action以后,页面并没有跳转,只是会在控制台输出 Action中的内容,往往我们在实际的开发中,处理了请求以后,还需要进行页面的跳转,如何完成 Struts2的页面的跳转呢?   这个时候我们需要修改改 Action类中的 execute方法法的返回值了,这个方法返回了一个 String类型,这个 String类型的值就是一个逻辑视图(逻辑视图:相相当于对一个真实的页面,取了一个别名)。那么我们来修改一个 Action类。

2.8 修改Action,将方法设置一个返回值

  修改Action中的execute方法的返回值,我们先任意给其返回一个字符串,比如返回一个 ok 的字符串。这个字符串就作为一个逻辑视图的名称。

代码语言:javascript
复制
package com.Kevin.action;

public class HelloAction {
    
    /**
     * 提供一个默认的执行的方法:execute
     * @return
     */
    public String execute(){
        System.out.println("HelloAction中的execute方法执行了------");
        return "ok";
    }
}

  返回一个 ok 的字符串了,这个字符串如何代表一个页面呢?我们就需要对struts2进行配置了。这个时候需要修改struts.xml,对Action的配置进行完善。

2.9 修改struts.xml

  打开struts.xml 文件,对action标签进行完善,在action标签中配置一个result标签,这个标签中的name属性就是之前方法返回的那个字符串的逻辑视图名称ok 。标签内部就是跳转的页面。 

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
    
<struts>
    <package name="hellodemo" extends="struts-default" namespace="/">
        <!-- name:访问名称 class:action位置 -->
        <action name="HelloAction" class="com.Kevin.action.HelloAction">
            <!-- 配置方法的返回值到页面 -->
            <result name="ok">/hello.jsp</result>
        </action>
    </package>

</struts>    

  到这里,我们的整个程序就执行完毕了,可以启动服务器并且测试项目。

打开页面:

页面跳转:

三、Struts2开发流程分析

3.1 Struts2的执行流程

  从客户端发送请求过来先经过前端控制器(核心过滤器 StrutsPreparedAndExecuteFilter )过滤器中执行一组拦截器(一组拦截器就会完成部分功能代码码),到底哪些拦截器执行了呢,在 Struts2中定义很多拦截器,在其默认栈中的拦截器会得到执行,这个我们可以通过断点调试的方式测试,拦截器执行完成以后,就会执行目标 Action,在 Action中返回一个结果视图,根据 Result的配置进行页面的跳转。

 四、Struts2的常见配置

4.1 Action的配置

   Struts2框架的核心配置文件是 struts.xml文件,该文件主要用来配置 Action和请求的对应关系。 【< package>的配置】   Struts2框架架的核心组件是 Action和拦截器,它使用包来管理 Action和拦截器。每个包就是多个Action、多个拦截器、多个拦截器引用的集合。在 struts.xml文件中,package元素用于定义包配置每个 package元素定义了一个包配置。 package元素的常用属性,如表所示。

  表中就是 package元素的常用属性,其中,在配置包时,必须指定name属性,就是包的标识。除此之外,还可以指定一个可选的 extends属性,extends属性值必须是另一个包的name属性值,但该属性值通常都设置为 struts-default,这样该包中的 Action就具有了 Struts2框架默认的拦截器等功能了。除此之外外,Struts2还提供了一种所谓的抽象包,抽象包不能包含 Action定义。为为了显式指定个包是抽象包,可以为该 package元素增增加 abstract="true"属性。   在 package中还有 namespace的配置,namespace属性与 action标签的name属性共同决定了访问路径。namespace有如下三种配置:

●  默认名称空间:默认的名称空间就是 namespace=""   ●  跟名称空间:跟名称空间就是 namespace="/"   ●  带名称的名称空间:带名称的名称空间就是 namespace="/demo1" 【 Action的配置】   Action映射是框架中的基本“工作单元”。 Action映射就是将一个请求的URL映射到一个 Action类,当一个请求匹配某个 Action名称时,框架就使用这个映射来确定如何处理请求。在 struts.xml文件中,通过< action>元素对请求的 Action和 Action类进行配置< action>元素中共有4个属性,这4个属性的说明如表所示。

  其中name属性和 namespace属性共同决定了访问路径,class对应的是 Action类的全路径。Method指定了执行 Action的那个方法,默认是 execute方法。

  基本的 Struts2的配置我们己经了解了,在实际的开发中我们需要大量的用到到 Struts2的常量,那么我们接下来学习一下 Struts2的常量。

4.2 模块开发的配置

  在实际开发中,我们通常很多人都需要修改同一个配置文件就是 struts.xml。因为这个文件是Struts2的核心配置文件。而且这个文件一且改错了一点,那么会导致整个项目都会出现问题,所以Struts2提供了< include>标签解决这个问题。   < include>元素用来在一个 struts.xml 配置文件中包含其他的配置文件,包含配置体现的是软件工程中的“分而治之”原则。 Struts2允许将一个配置文件分解成多个配置文件,从而提高配置文件的可读性。 Struts2默认只加载WEB-INF/ classes下的 struts.xml文件,但一且通过多个xml文件来配置Action,就必须通过 struts.xml文件来包含其他配置文件   为了让大家更直观地理解如何在 struts.xml文件中进行包含配置,接下来通过一段示例代码来说明,具体如下

代码语言:javascript
复制
<struts>    
        <!-- 包含了4个配置文件 -->
    <!-- 不指定路径,默认路径在src下的方式 -->
    <include file="struts-user.xml"></include>
    <include file="struts-customer.xml"></include>
    <include file="struts-book.xml"></include>
    <!-- 配置文件在具体包中时的方式 -->
    <include file="com.Kevin.action.hello.xml"></include>
</struts>    

  在上述代码片段中,struts.xml文件包含了4个配置文件,这4个配置文件都包含在 <include>元素中。配置< include>元素时,指定了一个必需的file属性,该属性指定了被包含配置文件的文件名。上述 include元素的file属性中,前3个没有指定文件所在路径时,表示该文件在项目的src路径下,如果配置文件在具体的包中,那么引入配置文件时,需要包含文件所在包的路径。   需要注意的是,每一个被包含的配置文件都是标准的 Struts2配置文件,一样包含DTD信息Struts2配置文件的根元素等信息。通过将 Struts2的所有配置文件都放在Web项目的WEB- INF/classes路径下, struts.xml文件包含了其他的配置文件,在 Struts2框架自动加载 struts.xml文件时,完成加载所有的配置信息。   Action的基本配置以及熟悉了,那么通过配置 Struts2框架就可以找到具体的 Action类了,那么Action类又要如何编写呢?接下来学习 Action类的编写的方式。

五、Struts2的Action访问

  在 Struts2的应用开发中,Action作为框架的核心类,实现对用户请求的处理,Action类被称为业务逻辑控制器。一个 Action类代表一次请求或调用,每个请求的动作都对应于一个相应的 Action类,一个 Action类是一个独立的工作单元。也就是说,用户的每次请求,都会转到一个相应的 Action类里面,由这个 Action类来进行处理。简而而言之,,Action就是用来处理一次用户请求的对象。

  实现 Action控制类共有3种方式,接下来,分别别对它们进行讲解,具体如下:

5.1 Action的编写方式

【 Action的是一个POJO的类】   在 Struts2中,Action可以不继承特殊的类或不实现任何特殊的接口,仅仅是一个POJO。POJO全称 Plain Ordinary Java Object(简单的Java对象),只要具有一部分 getter/ setter方法的那种类,就可以称作POJO。一般在这个POJO类中,要有一个公共的无参的构造方法(采用默认的构造方法就可以)和一个 execute方法。定义格式如下:

代码语言:javascript
复制
package com.Kevin.action;

public class HelloAction {
    
    /**
     * 提供一个默认的执行的方法:execute
     * @return
     */
    public String execute(){
        System.out.println("HelloAction中的execute方法执行了------");
        return "ok";
    }
}

execute( )方法的要求如下:   ●  方法的权限修饰符为 public。   ●  返回一个字符串,就是指示的下一个页面的 Result。   ●  方法没有参数。 也就是说,满足上述要求的POJO都可算作是 Struts2的 Action实现。 通常会让开发者自己编写 Action类或者者实现 Action接口或者继承 Actionsupport类。

【 Action类实现一个 Action的接口】   为了让用户开发的 Action类更规范,Struts2提供一个 Action接口,用户在实现 Action控制制类时,可以实现 Struts2提提供的这个 Action接口。 Action接口定义了 Struts的的 Action处理理类应该实现的规范,Action接口中的具体代码如下所示。

代码语言:javascript
复制
package com.Kevin.action;

import com.opensymphony.xwork2.Action;

public class UserAction implements Action{
    @Override
    public String execute() throws Exception {
        System.out.println("实现了Action接口----------");
        return NONE;
    }

}

  从上述代码中可以看出,Action接接口位于 com.opensymphony.xwork2包中。这个接口里只定义了一个execute( )方法,该接口的规范规定了 Action处理类应该包含一个 execute方法,该方法返返回一个字符串。除此之外,该接口还定义了5个字符串常量,它们的作用是统一 execute( )方法的返回值。 Action接口中提供了5个已经定义的常量如下:   ●  SUCCESS:success,代表成功。   ●  NONE:none,代表页面不跳转。 ●  ERROR:error,代表跳转到到错误页面。 ●  INPUT:input,数据校验的时候跳转的路径。  ●  LOGIN:login,用来跳转到登录页面。 由于 Xwork的 Action接口简单,为开发者提供的帮助较小,所以在实际开发过程中,Action类很少直接实现Action接口,通常都是从ActionSupport类继承。

【Action类继承ActionSupport类】(推荐)

代码语言:javascript
复制
package com.Kevin.action;

import com.opensymphony.xwork2.ActionSupport;

public class PersonAction extends ActionSupport{
    
    public String execute(){
        System.out.println("继承ActionSupport类----------");
        return NONE;
    }

}

  ActionSupport 类本身实现了 Action接口,是 Struts2中默认的 Action接口的实现类,所以继承ActionSupport 就相当于实现了 Action接口。 ActionSupport 类还实现了 Validateable、ValidationawareTextprovider、Localeprovider、和 Serializable等接口,来为用户提供更多的功能。   ActionSupport 类中提供了许多默认方法,这些默认方法包括获取国际化信息的方法、数据校验的方法、默认的处理用户请求的方法等。实际上,ActionSupport 类是 Struts2默认的 Action处理类。如果让开发者的 Action类继承该 ActionSupport 类,则会大大简化 Action的开发。   Action的类已经会编写了,如果要执行这个 Action,可以通过前面的配置来完成,但是之前的方式有一个缺点,就是多次请求不能对应同一个 Action,因为实际的开发中,一个模块的请求通常由一个 Action类处理就好了,否则则会造成 Action类过多。那么接下来我们讲一下 Action访问的一些细节。

5.2 Action的访问

  Action的访问不是难题,因为之前已经访问过了,但是出现一个问题。一次请求现在对应一个Action,那么如果请求很多对应很多个 Action。现在要处理的问题就是要让一个模块的操作提交到一个 Action中。   其实我们学过在< action>的标签中有一个属性 method,通通过 method的配置来指定 Action中的某个方法执行。 【解决 Action的访问的问题的方式一:通通过配置 method属性完成】

编写测试代码如下:

BookAction类:

代码语言:javascript
复制
package com.Kevin.method;

import com.opensymphony.xwork2.ActionSupport;

public class BookAction extends ActionSupport{
    
    public String add(){
        System.out.println("add----");
        return NONE;
        
    }
    
    public String update(){
        System.out.println("update-----");
        return NONE;
    }

}

struts.xml中配置:

代码语言:javascript
复制
    <!-- 配置method方法访问 -->
    <package name="methoddemo" extends="struts-default" namespace="/">
        <action name="addAction" class="com.Kevin.method.BookAction" method="add"></action>
        <action name="updateAction" class="com.Kevin.method.BookAction" method="update"></action>
    </package>

但是这种方式我们会发现,同一个 Action类就被配置了很多次,只是修改了后面的 method的值。那么能不能配置简单化呢?也就是一个 Action类,只配置一次就好了?这个时候我们就需要使用通配符的配置方式了。 【解决 Action的访问的问题的方式二:通过通配符的配置完成】 编写测试代码如下:

BookAction类:

代码语言:javascript
复制
package com.Kevin.method;

import com.opensymphony.xwork2.ActionSupport;

public class BookAction extends ActionSupport{
    
    public String add(){
        System.out.println("add----");
        return NONE;
        
    }
    
    public String update(){
        System.out.println("update-----");
        return NONE;
    }

}

struts.xml中配置:

代码语言:javascript
复制
    <!-- 通配符方式实现 -->
    <package name="methoddemo2" extends="struts-default" namespace="/">
        <!-- 
            name属性值里加符号 *
            1.执行action中的add方法,访问book_add
            2.执行actoin中的update方法,访问book_update
            上述两个路径使用book_* 就可匹配到
         -->
        <action name="book_*" class="com.Kevin.method.BookAction" method="{1}"></action>
    </package>

【解决 Action的访问的问题的方式三:动态方法访问】(一般不用)   动态方法访问在 Struts2中默认是不开启的,如果想要使用需要先去开启一个常量。

代码语言:javascript
复制
<constant name="struts.enable.DynamicMethodInvocation" value=true"></constant>

  动态方法访问主要的控制是在页面端,所以编写 Action和和配置 Action都很简单,关键是访问路径的编写。 由于不经常使用,笔者在这里就不做过多介绍,有兴趣的朋友可自行查阅。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-05-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档