(转)Struts2快速入门

http://blog.csdn.net/yerenyuan_pku/article/details/66187307

Struts2框架的概述

Struts2是一种基于MVC模式的轻量级Web框架,它自问世以来,就受到了广大Web开发者的关注,并广泛应用于各种企业系统的开发中。目前掌握Struts2框架几乎成为Web开发者的必备技能之一。接下来将针对Struts2的特点、安装以及执行流程等内容进行详细的讲解。

什么是Struts2

先讲Struts2框架之前,我们得知道JavaEE一共有三层架构,如下:

架构名称所使用框架
Web层 Struts2
Service层 Spring
Dao层 Hibernate

接下来我们就来解释什么是Struts2,可从度娘上摘抄如下字段:

Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个Servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts2是Struts的下一代产品,是在Struts1和WebWork的技术基础上进行了合并的全新的Struts2框架。其全新的Struts2的体系结构与Struts1的体系结构差别巨大。Struts2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts2可以理解为WebWork的更新产品。虽然从Struts1到Struts2有着太大的变化,但是相对于WebWork,Struts2的变化很小。

从以上这段话可得出如下两点结论:

  1. Struts2是应用在Web层的框架。
  2. Struts2是在Struts1和WebWork框架基础之上发展的全新的框架。

在介绍Struts2之前,先来认识一下Struts1。Struts1是最早的基于MVC模式的轻量级的Web框架,它能够合理的划分代码结构,并包含验证框架、国际化框架等多种实用工具框架。但是随着技术的进步,Struts1的局限性也越来越多的暴露出来。为了符合更加灵活、高效的开发需求,Struts2框架应运而生。 
Struts2是Struts1的下一代产品,是在Struts1和WebWork技术的基础上进行合并后的全新框架(WebWork是由OpenSymphony组织开发的,致力于组件化和代码重用的J2EE Web框架,它也是一个MVC框架)。虽然Struts2的名字和Struts1相似,但其设计思想却有很大不同。实质上,Struts2是以WebWork为核心的,它采用拦截器的机制来处理用户的请求。这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts2可以理解为WebWork的更新产品。 
Struts2拥有优良的设计和功能,其优势具体如下:

  • 项目开源,使用及拓展方便,天生优势。
  • 提供Exception处理机制。
  • Result方式的页面导航,通过Result标签很方便的实现重定向和页面跳转。
  • 通过简单、集中的配置来调度业务类,使得配置和修改都非常容易。
  • 提供简单、统一的表达式语言来访问所有可供访问的数据。
  • 提供标准、强大的验证框架和国际化框架。
  • 提供强大的、可以有效减少页面代码的标签。
  • 提供良好的Ajax支持。
  • 拥有简单的插件,只须放入相应的JAR包,任何人都可以扩展Struts2框架,比如自定义拦截器、自定义结果类型、自定义标签等,为Struts2定制需要的功能,不需要什么特殊配置,并且可以发布给其他人使用。
  • 拥有智能的默认设置,不需要另外进行繁琐的设置。使用默认设置就可以完成大多数项目程序开发所需要的功能。

上面列举的就是Struts2的一系列技术优势,只需对它们简单了解即可,在学习了后面的知识后,会慢慢对这些技术优势有更好的理解和体会。 
那么除了Struts2之外,还有哪些优秀的WEB层框架呢?

常见的Web层框架

常见的Web层框架有:

  • Struts2
  • Struts1
  • WebWork
  • SpringMVC

Web层框架都会有一个特点,那就是基于前端控制器模式实现的。我们也可复习一下常见的Dao层框架有哪些?

  • Hibernate
  • MyBatis
  • DBUtils
  • Spring JDBC Template

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

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

这里写图片描述
了解这些之后,我们来进行一个Struts2的快速入门,来感受一下Struts2的优势吧!

Struts2快速入门

下载Struts2的开发包

Struts2的官网为:https://struts.apache.org/ 

我们这里使用struts-2.3.24版本的Struts2为大家讲解,下载好了以后需要进行解压。

解压Struts2的开发包

解压后的目录结构如下: 

从图中可以看出,展示的是解压后的struts-2.3.24的目录结构,为了让大家对每个目录的内容和作用有一定的了解,接下来针对这些目录进行简单介绍,具体如下:

  • apps:该文件夹用于存放官方提供的Struts2示例程序,这些程序可以作为学习者的学习资料,可为学习者提供很好的参照。各示例均为war文件,可以通过zip方式进行解压。
  • docs:该文件夹用于存放官方提供的Struts2文档,包括Struts2的快速入门、Struts2的文档以及API文档等内容。
  • lib:该文件夹用于存放Struts2的核心类库,以及Struts2的第三方插件类库。
  • src:该文件夹用于存放该版本Struts2框架对应的源代码。

有了Struts2的开发环境,接下来我们可以进行Struts2的开发了。

创建一个Web工程引入相应JAR包

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

这些包就是Struts2的基本的开发包了,那么这些包都是什么含义呢?Struts2项目依赖的基础Jar包说明: 

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

编写一个Action

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

/**
 * 作为一个action
 * @author 李阿昀
 *
 */
public class UserAction {

    public String execute() {
        return "ok";
    }

}

对于Servlet来说,每次访问Servlet的时候,都会执行Servlet里面的service()方法。而对于Action来说,每次访问Action的时候,默认执行Action里面名称为execute的方法。注意:创建方法的要求是方法不能有参数。 
Action类编写好了以后,Struts2框架如何识别它就是一个Action呢?那么我们需要对Action类进行配置。

完成Action的配置

这个时候,我们还需要观察apps中的示例代码,在WEB-INF的classes目录下,有一个名称为struts.xml的文件,这个文件就是Struts2的配置文件。 
我们在开发中需要将struts.xml文件引入到工程的src下,因为src下的内容发布到Web服务器就在WEB-INF下的classes中了。将struts.xml中的原有内容删除掉,然后配置上自己编写的Action类就可以了。配置内容如下:里面的具体的标签,我们会在后面的地方详细介绍。

<?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>                                         <!-- namespace必须以/开头 -->
    <package name="demo1" extends="struts-default" namespace="/">
        <!-- name绝不能以/开头 -->
        <action name="user" class="cn.itcast.action.UserAction">
            <result name="ok">/user.jsp</result>                
        </action>
    </package>
</struts>

紧接着在WebRoot目录下创建一个页面——user.jsp,该页面的内容为:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>Hello Struts2!!!</h1>
</body>
</html>

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

配置核心过滤器

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

<!-- 配置Struts2的过滤器 -->
<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>

至此,我们可在浏览器地址栏输入地址http://localhost:8080/struts2_day01/user.action,访问Action,即能出现如下界面: 

注意:后缀名(.action),这个后缀名可以不写,建议写出来。 
到这里Struts2的入门案例已经编写完成了,那么我们来总结下Struts2的整个流程。

Struts2开发流程分析

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

以上就是Struts2的大致上的执行流程,我觉得我已经画的够清晰了,如果您认为上图不完整,可参考官网提供的图: 

Struts2的常见配置

通过前面的学习,我们已对Struts2框架有了一定的了解,但是对于各个知识点的细节,还需要进一步地学习。接下来,将针对Struts2中struts.xml文件的配置等内容进行详细的讲解。在学习具体详细的配置之前,要对Struts2的配置文件的加载顺序有一定的了解,这样对后面学习Struts2的配置都是有帮助的。

Struts2的配置文件的加载顺序

每次从客户端发送请求到服务器都要先经过Struts2的核心过滤器StrutsPrepareAndExecuteFilter,这个过滤器有两个功能:预处理和执行。在预处理中主要就是来加载配置文件的。对应的是过滤器中的init方法,而执行是用来执行一组拦截器完成部分功能的,对应的是过滤器的doFilter方法。所以我们如果要去了解Struts2的配置文件的加载顺序,那么我们需要查询过滤器的init方法。 

在init方法中,调用了init的initDispatcher的方法来加载配置文件,进入到该代码中: 

我们会发现这个方法又调用了dispatcher的init方法,进入init方法内部: 

这一系列的代码就是用来加载Struts2的配置文件的。

init_DefaultProperties(); // [1]

加载org/apache/struts2/default.properties,该文件配置的是Struts2的所有的常量。

init_TraditionalXmlConfigurations(); // [2]

加载struts-default.xml、struts-plugin.xml、struts.xml

init_LegacyStrutsProperties(); // [3]

加载用户自定义的struts.properties。

init_CustomConfigurationProviders(); // [5]

加载用户配置的提供对象。

init_FilterInitParameters() ; // [6]

加载web.xml。

init_AliasStandardObjects() ; // [7]

加载标准对象。 
根据上面的代码我们可以得出配置文件的加载顺序,如下:

  1. default.properties
  2. struts-default.xml
  3. struts-plugin.xml
  4. struts.xml,配置Action以及常量。
  5. struts.properties,配置常量。
  6. web.xml,配置核心过滤器以及常量。

前三个配置文件我们不用关心,是Struts2内部的配置文件,我们无法修改,能修改的文件就是struts.xml、struts.properties、 web.xml配置文件。这几个配置文件的加载是有一定顺序的。这三个配置文件都可以修改Struts2的常量的值,要记住的是,后加载配置文件中常量的值会将先加载的配置文件中常量的值给覆盖掉。 
知道了这些,我们就可以来看Struts2的详细的配置了。首先来看package的配置。

package的配置

Struts2框架的核心配置文件是struts.xml文件,该文件主要用于配置Action和请求的对应关系。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”

注意:在一个配置文件中可以有多个package标签,而且package标签中的name属性值不能相同。

action的配置

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

其中name属性和namespace属性共同决定了访问路径,class对应的是Action类的全路径。Method指定了执行Action的那个方法,默认是execute方法。 
注意:在一个package标签里面可以写多个action标签,并且action标签的name属性值不能一样。如:

<package name="demo1" extends="struts-default" namespace="/">
    <action name="user" class="cn.itcast.action.UserAction">
        <result name="ok">/user.jsp</result>                
    </action>
    <action name="person" class="cn.itcast.action.PersonAction">
        <result name="success">/person.jsp</result>
    </action>
</package>

result的配置

Action类的方法是有返回值的,配置返回值之后,可跳转到不同的页面中。result标签里面的name属性值即是Action类里面的方法的返回值。如:

<result name="success">/person.jsp</result>

在一个action标签里面可写多个result标签,但要注意result标签的name属性值不能相同。 
基本的Struts2的配置我们已经了解了,在实际的开发中我们需要大量的用到Struts2的常量,那么我们接下来学习一下Struts2的常量。

Struts2常量的配置

Struts2的这些常量大多在默认的配置文件中已经配置好,但根据用户需求的不同,开发的要求也不同,可能需要修改这些常量值,修改的方法就是在配置文件中对常量进行重新配置。 
Struts2常量的配置共有3种方式,分别如下:

  • 在struts.xml文件中使用<constant>元素配置常量。
  • 在struts.properties文件中配置常量。
  • 在web.xml文件中通过<init-param>元素配置常量。

为了让大家更好地掌握这3种Struts2常量配置的方式,接下来分别对它们进行讲解,具体如下:

  1. 在struts.xml文件中通过<constant>元素配置常量 
    在struts.xml文件中通过<constant>元素来配置常量,是最常用的方式。在struts.xml文件中通过<constant.../>元素来配置常量时,需要指定两个必填的属性name和value。

    • name:该属性指定了常量的常量名。
    • value:该属性指定了常量的常量值。

    在struts.xml文件中配置的示例代码如下:

    <struts>
        <!-- 设置默认编码集为UTF-8 -->
        <constant name="struts.i18n.encoding" value="utf-8">
        <!-- 设置使用开发模式 -->
        <constant name="struts.devMode" value="true">
    </struts> 
  2. 在上述示例代码中,配置了常量struts.i18n.encoding和struts.devMode,用于指定Struts2应用程序的默认编码集为UTF-8,并使用开发模式。值得一提的是,struts.properties文件能配置的常量都可以在struts.xml文件中使用<constant>元素来配置。 
    注意,我还须对struts.i18n.encoding这个常量作进一步的解释。这个常量封装了一个功能,如若将其值置为UTF-8,使用Struts2的Action类得到表单的提交数据,并且表单提交方式是post,那么提交中文时的中文乱码问题使用这个常量就能帮我们处理了,而不需要自己手动设置编码方式。

  3. 在struts.properties文件中配置常量 
    struts.properties文件是一个标准的properties文件,其文件格式为key-value对,即每个key对应一个value,key表示的是Struts2框架中的常量,而value则是其常量值。在struts.properties文件中配置常量的方式,具体如下所示:

    
    ### 设置默认编码集为UTF-8
    
    struts.i18n.encoding=UTF-8
    
    ### 设置action请求的扩展名为action或者没有扩展名
    
    struts.action.extension=action,,
    
    ### 设置不使用开发模式
    
    struts.devMode=false
    
    ### 设置不开启动态方法调用
    
    struts.enable.DynamicMethodInvocation=false
    • 1

    在上述代码片段中,“=”号左边的是key,右边的是每个key对应的value,另外,代码片段中的“###”表示的是properties文件中的注释信息,用于解释说明。需要注意的是,和struts.xml文件一样,struts.properties文件也应存放于WEB-INF/classes路径下。

  4. 在web.xml文件中通过初始化参数配置常量 
    在web.xml文件中配置核心过滤器StrutsPrepareAndExecuteFilter时,通过初始化参数来配置常量。通过<filter>元素的<init-param>子元素指定,每个<init-param>元素配置了一个Struts2常量。在web.xml文件中通过初始化参数配置常量方式,具体如以下代码片段所示:

    <!-- 配置Struts2的过滤器 -->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        <!-- 通过init-param元素配置Struts2常量,配置默认编码集为UTF-8 -->
        <init-param>
            <param-name>struts.i18n.encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
  5. 在上述web.xml文件的代码片段中,当配置StrutsPrepareAndExecuteFilter时,还可通过<init-param>子元素配置常量struts.i18n.encoding,指定其值为UTF-8。需要注意的是,在web.xml文件中配置常量时,<init-param>标签必须放在<filter>标签下。

Struts2所支持的常量数量众多,在struts2-core-2.3.24.jar压缩文件的org/apache/struts2路径下有一个default.properties文件,该文件里为Struts2的所有常量都指定了默认值,读者可以通过查看该文件来了解Struts2所支持的常量。 
之前,我们就已经介绍过了Struts2的配置文件的加载顺序,后加载的配置文件的常量的值会覆盖先加载的配置文件中常量的值,所以这个地方大家要注意。 
在实际的开发中我们更习惯使用struts.xml修改Struts2的常量。但是在实际开发中还会有一个问题,就是如果一个项目是团队开发的,也就是很多人开发的,那么团队中的很多人就都需要去修改struts.xml,那么最后在项目整合的时候就会很麻烦。所以Struts2中也支持分模块开发的配置。

分模块开发的配置

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

<struts>
    <!-- 包含了4个配置文件 -->
    <!-- 不指定路径默认在src下时的方式 -->
    <include file="struts-shop.xml"></include>
    <include file="struts-user.xml"></include>
    <include file="struts-shoppingcart.xml"></include>
    <!-- 配置文件在具体包中时的方式 -->
    <include file="cn/itcast/action/struts-product.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种方式,接下来,分别对它们进行讲解,具体如下。

Action的编写方式

Action的编写方式共有三种方式,如下。

创建普通类,不继承任何类,不实现任何接口

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

public class UserAction {

    public String execute() {
        return "ok";
    }

}

execute()方法的要求为:

  • 方法的权限修饰符为public
  • 返回一个字符串,就是指示的下一个页面的result
  • 方法没有参数

也就是说,满足上述要求的POJO都可算作是Struts2的Action实现。通常会让开发者自己编写Action类或者实现Action接口或者继承ActionSupport类。

Action类实现一个Action接口

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

public class CustomerAction implements Action {

    public String execute() throws Exception {

        return SUCCESS;
    }

}

从上述代码中可以看出,Action接口位于com.opensymphony.xwork2包下。这个接口里只定义了一个execute()方法,该接口的规范规定了Action处理类应该包含一个execute()方法,该方法返回一个字符串。除此之外,该接口还定义了5个字符串常量,它们的作用是统一execute()方法的返回值。 
Action接口中提供了5个已经定义的常量如下:

  • SUCCESS:success,代表成功
  • NONE:none,代表页面不跳转。在Action类的方法里面,如果返回了一个值,必须在action标签里写result标签进行配置,如果没有配置则返回404页面。
  • ERROR:error,代表跳转到错误页面
  • INPUT:input,数据校验的时候跳转的路径
  • LOGIN:login,用来跳转到登录页面

由于Xwork的Action接口简单,为开发者提供的帮助较小,所以在实际开发过程中,Action类很少直接实现Action接口,通常都是从ActionSupport类继承。

Action类继承ActionSupport类(推荐)

public class OrdersAction extends ActionSupport {

    // 添加
    public String add() {
        System.out.println("ADD........................");
        return NONE;
    }

    // 修改
    public String update() {
        System.out.println("UPDATE........................");
        return NONE;
    }
}

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

访问Action的方法

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

解决Action访问的问题的方式一:通过配置method属性完成

编写Action:

public class OrdersAction extends ActionSupport {

    // 添加
    public String add() {
        System.out.println("ADD........................");
        return NONE;
    }

    // 修改
    public String update() {
        System.out.println("UPDATE........................");
        return NONE;
    }

}

配置Action:

<package name="demo" extends="struts-default" namespace="/">
    <!-- 要action的add方法执行,method属性:要执行的方法名称add -->
    <action name="addAction" class="cn.itcast.action.OrdersAction" method="add"></action>
    <!-- 要action的update方法执行,method属性:要执行的方法名称update -->
    <action name="updateAction" class="cn.itcast.action.OrdersAction" method="update"></action>
</package>

但是这种方式我们会发现,同一个Action类就被配置了很多次,只是修改了后面的method的值。那么能不能配置简单化呢?也就是一个Action类,只配置一次就好了?这个时候我们就需要使用通配符的配置方式了。

解决Action访问的问题的方式二:通过通配符的配置完成

Action类还是上面的OrdersAction,只是我们的核心配置文件要修改为:

<package name="demo" extends="struts-default" namespace="/">
    <action name="order_*" class="cn.itcast.action.OrdersAction" method="{1}"></action>
</package>

<action>的name属性中使用的*号代表任意字符,method中的{1}代表name属性中的出现的第一个*号所代替的字符。 
这个时候我们就只配置一个Action类就可以了,在上述代码中,当客户端发送/order_add.action这样的请求时,action元素的name属性就被设置成order_add,method属性就被设置成add。当客户端发送/order_update.action这样的请求时,action元素的name属性就被设置成order_update,method属性也被设置成update。 
当然使用通配符是开发中常用的方式,Struts2还有一种解决这类问题的办法,这种大家可以作为扩展内容来学习。

解决Action访问的问题的方式三:动态方式访问

动态方法访问在Struts2中默认是不开启的,如果想要使用需要先去开启一个常量。

<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>

动态方法访问主要的控制是在页面端,所以编写Action和配置Action都很简单,关键是访问路径的编写。 
Action类还是上面的OrdersAction,只是我们的核心配置文件要修改为:

<package name="demo" extends="struts-default" namespace="/">
    <action name="order" class="cn.itcast.action.OrdersAction"></action>
</package>

访问路径的写法:

  1. http://localhost:8080/struts2_day01/order!add.action
  2. http://localhost:8080/struts2_day01/order!update.action
原文地址:https://www.cnblogs.com/telwanggs/p/6970434.html