Struts2第一天
1.为什么要学习Struts2
先分析我们之前所写的Servlet:
分析以上我们所熟悉的Servlet的代码,可以得出如下结论:
1、传统代码的弊端:在Servlet里存在获取请求参数、页面跳转代码冗余的问题。
2、Struts2的优势:可以解决Servlet里获取请求参数、页面跳转代码用于的问题。
Struts2概述
2.1.什么是Struts2
用一句话概括:Struts2是一个基于MVC设计模式的WEB层框架。
2.2.MVC设计模式
MVC,全名是Model View Controller,是模型(Model)-视图(View)-控制器(Controller)的缩写,是一种软件设计模式,或软件设计思想。以下是MVC的具体含义:
1、Model:数据模型,用来处理数据,一般是一个实体类,例如User类;
2、View:视图,用来显示界面,可以是JSP或Html;
3、Controller:控制器,用来决定哪个界面来展示数据模型;
MVC的目的是将M和V的实现代码分离。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。
MVC设计模式其实是一种软件设计思想,可以把设计思想理解成接口;MVC设计模式有多种实现方式,其中,JSP+Servlet+JavaBean就是其中的实现方式之一。
但是,JSP+Servlet+JavaBean这种实现方式中,Servlet存在着接收请求参数、页面跳转代码冗余的问题。所以,这种实现方式不是最好的MVC的实现。Struts2框架就是一种更好的MVC设计模式的实现方式。
2.3.Struts2在项目中的角色
JavaEE开发规范规定,一个Java web项目应该要分为三层:
1、WEB层:页面数据显示、页面跳转调度;
2、业务层:业务处理和功能逻辑、事务控制;
3、持久层:数据存取和封装、和数据库打交道;
注意:MVC和JavaEE三层架构规范不是同一个概念,一定要区分开来。
2.4.Struts2的软件开发包
官网地址:http://struts.apache.org/
点击Download下载软件开发包,官网提供的最新版本是2.5.10.1.
本课程使用的版本是2.3.24
把struts-2.3.24-all.zip解压,目录如下:
从图中可以看出,展示的是解压后的Struts2.3.24的目录结构,为了让大家对每个目录的内容和作用有一定的了解,接下来针对这些目录进行简单介绍,具体如下:
apps:该文件夹存用于存放官方提供的Struts2示例程序,这些程序可以作为学习者的学习资料,可为学习者提供很好的参照。各示例均为war文件,可以通过zip方式进行解压。
docs:该文件夹用于存放官方提供的Struts2文档,包括Struts2的快速入门、Struts2的文档,以及API文档等内容。
lib:该文件夹用于存放Struts2的核心类库,以及Struts2的第三方插件类库。
src:该文件夹用于存放该版本Struts2框架对应的源代码。
有了Struts2的开发环境,接下来我们可以进行Struts2的开发了。
3.Struts2快速入门
3.1.Struts2环境搭建
3.1.1.第一步:创建JavaEE工程,引入必备的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中查看。
然后,把以上13个jar包导入到你的工程里。
3.1.2.第二步:在web.xml中配置Struts2的核心过滤器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>struts2_day01</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!--
配置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>
</web-app>
3.1.3.第三步:在类的根路径下创建一个名叫struts.xml的文件,并导入约束
在src下新建struts.xml,文件名一般都是struts.xml,不要去改文件名。
struts.xml配置DTD信息:可从struts2-core.jar中的struts-2.3.dtd中复制。
如何配置XML自动提示?
如果电脑可以联网,自动从网上下载 DTD,在编写xml文件时就有了提示。
如果电脑没有联网,在本地配置DTD文件位置,提供本地提示。
配置XML自动提示步骤:
第一步:从struts.xml中复制dtd网址:
第二步:打开eclipse的Window–>Preferences–>XML Catalog:
第三步:点击Add添加dtd文件路径:
点击File System添加dtd文件的路径,dtd文件在源码中可以找到:struts-2.3.24\src\core\src\main\resources\struts-2.3.dtd
Key type选择URI,key填写我们之前复制的dtd网址
确定,重新打开struts.xml,就有了提示。
Struts2入门案例
需求:使用Struts2编写一个简单的请求与跳转的功能:在浏览器中输入请求地址,经过struts2框架,跳转到success.jsp页面。
案例实现
第一步:编写Action类,负责接收用户请求,并处理请求
/**
* 自定义的第一个Action类,需要继承ActionSupport
*/
public class HelloAction extends ActionSupport{
private static final long serialVersionUID = 1L;
/**
* 重写父类的execute方法,请求进来,默认执行execute方法
*/
@Override
public String execute() throws Exception {
//调用业务的代码
System.out.println("Hello World");
//框架获取到该方法的返回值,返回值对应的要跳转到页面
return "success";
}
}
第二步:在struts.xml中配置HelloAction类
<?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="default" namespace="/" extends="struts-default">
<!--
name:Action类的名字,具有唯一性,页面上通过name来访问Action类
-->
<action name="hello" class="cn.itcast.action.HelloAction">
<!-- 配置结果集 :name属性的值一定要与execute方法的返回值一致-->
<result>
/success.jsp
</result>
</action>
</package>
</struts>
第三步:在WebContent下新建success.jsp页面
3.2.2.4.第四步:启动Tomcat测试访问结果
启动tomcat,在浏览器中输入地址:http://localhost:8080/struts2_day01/hello.action
或http://localhost:8080/struts2_day01/hello
注意:Struts2框架规定action默认的后缀名就是action,也可以不写,一般都带上action。
Struts2的执行过程
程序基本运行流程分析
Struts2的内部运行原理
拦截器:对请求做出一些处理,每个拦截器对应一个功能(公用的,重要的),帮Action处理一些重复的重要的事情,拦截完之后,请求再进入Action,此时Action只需要关注业务逻辑。
那么在调用Action之前会经过哪些拦截器了?
我们可以参考 struts-core.jar 提供 struts-default.xml 配置文件
默认情况下, 访问每个Action ,默认拦截器defaultStack里的拦截器都会执行。
这里我们挑选modelDriven和fileUpload两个拦截器,打开其源码,添加断点,采用debug启动观察请求是否经过了这两个拦截器
为了能在拦截器中打断点,需要关联Struts2的源码。步骤如下:
第一步:确定你要观察的类在哪个jar包中。modelDriven拦截器类在xwork-core.jar包中,fileUpload拦截器在struts-core.jar包中,所以需要关联xwork-core.jar、struts-core.jar这两个jar包的源码。
第二步:右键该jar包,选择Java Source Attachment—>External location—>External File,选中Struts2官方发布包压缩包。
第三步:点击Apply,再点击OK。
那么我们该如何查看源代码呢?随便挑选几个拦截器,选中拦截器类
按下shift+ctrl+T打开搜索输入框
点击OK,即可打开源码。
3.4.Lib目录中的jar包介绍(了解)
asm-.jar:字节码操作类库 (.class文件)
commons-fileupload-1.2.2.jar:文件上传组件,2.1.6版本后需要加入此文件。
commons-io-2.0.1.jar:上传文件依赖的jar包。
commons-lang-2.5.jar:对java.lang包的增强,主要是提供字符串等操作的公用方法。
freemarker-2.3..jar:模版引擎,struts2标签库,依赖freemarker ,Struts 2的UI标签的模板使用FreeMarker编写。
javassist*.jar 生成代理的类库。
log4j-api.jar:log4j日志接口。
log4j-core.jar:log4j日志实现
ognl-3.0.x.jar:OGNL对象图导航语言(Object Graph Navigation Language), struts2框架通过其读写对象的属性。(类似于EL但更强大)
struts2-core-2.3.x.jar:Struts 2框架的核心类库。
xwork-core-2.3.x.jar:Command命令模式框架, Struts2和WebWork都基于和依赖xwork。
Struts2配置文件详解
配置文件的分类
框架内置的配置文件(有三个)
default.properties:在struts2-core.jar的org.apache.struts2包中,存放了Struts2所有的常量信息
struts-default.xml:在struts2-core.jar中,定义了Struts2框架底层的一些bean,struts-default抽象包,拦截器、结果集
struts-plugin.xml:可有可无,在某个插件的jar包中,定义了插件中的bean、action等信息
自定义的配置文件(有三个)
struts.xml:是strust2的核心配置文件,位于工程的src目录下,主要用于配置用户自定义的Action类
struts.properties:可有可无,位于工程的src目录下,用户可以添加,也可以不添加,用于配置Sturts2的常量
web.xml:在WEB-INF下,也可以配置Struts2的常量
配置文件加载的顺序
Struts2框架中的六个配置加载顺序如下:
default.properties—>struts-default.xml—>struts-plugin.xml—>struts.xml—>struts.properties—>web.xml
补充:从源码的角度来分析各种配置文件的加载顺序
(1)Struts2项目启动时,会调用过滤器的init方法完成初始化;(参考StrutsPrepareAndExecuteFilter的第57行代码,InitOperations第74行代码)
(2)初始化时,先加载default.properties文件;(参考Dispatcher类第483行代码)
(3)再加载,struts-default.xml、struts-plugin.xml、struts.xml文件;(参考Dispatcher类第484行代码)
(4)再加载struts.properties;(参考Dispatcher类第485行代码)
(5)再加载web.xml配置的初始化参数;(参考Dispatcher类第486行代码)
核心配置文件struts.xml(重点)
constant标签
作用:
用于修改struts2中的常量
属性:
name:指定常量的key
value:指定常量的值
用法:
<!-- 开启开发者模式 -->
<constant name="struts.devMode" value="true"></constant>
常用常量介绍:
常量名 常量值 说明
- struts.i18n.encoding UTF-8 应用中使用的编码
- struts.objectFactory.spring.autoWire name 和spring框架整合有关
- struts.multipart.parser jakarta 指定文件上传用的组件
- struts.multipart.maxSize 2097152 文件上传总文件大小限制:2M
- struts.action.extension action, 能进入Struts2框架内部的url地址后缀名。多个值用逗号分隔
- struts.enable.DynamicMethodInvocation false 是否允许动态方法调用
- struts.devMode false 是否是开发模式。开发模式:改了配置文件,不需要重启。输出更多的错误信息。开发阶段建议为true。
- struts.ui.theme xhtml 页面展示用的主题
开启开发者模式的好处:
(1)当发生异常后,可以在页面上看到详细的异常信息
(2)当更改了配置文件,自动重载配置文件,不需要重启服务,提高开发效率
说明:常量还可以在struts.properties和web.xml中配置,但是我们一般就在struts.xml配置常量。
package标签
作用:
在struts2的配置文件中引入了面向对象思想,使用了分包管理。易于管理Action类。便于模块化开发Action类。
属性:
- name: 包的名称。必须写。且必须唯一。
- extends: 一般情况下需要继承struts-default包,但不是必须的。不过如果不继承的话,将无法使用struts2提供的核心功能。struts-default.xml中定义着struts-default这个包。而struts-default.xml是在我们的struts.xml加载之前加载。
- abstract: 把包声明为抽象包,抽象包就是用来被继承的。只要是没有元素的包,就可以声明为抽象包。
- namespace: 名称空间。它的作用是把访问的URL按照模块化来管理。 名称空间的写法:
一般以/开头
当我们指定了名称空间之后,访问的URL就变成了:
名称空间+action标签的name属性取值
例如:
/n1/hello.action
/customer/addCustomer.action
/customer/editCustomer.action
/linkman/findAllLinkMan.action
/linkman/removeLinkMan.action
用法:
<package name="default" namespace="/" extends="struts-default">
<action name="hello" class="cn.itcast.action.HelloAction">
<result>
/success.jsp
</result>
</action>
</package>
<package name="myDefault" namespace="/test" extends="struts-default">
<action name="hello2" class="cn.itcast.action.Hello2Action">
<result>
/success.jsp
</result>
</action>
</package>
下面演示namesapace的具体用法:
struts.xml中自定义了一个default包,namespace是/,父包是struts-default,该包下hello这个action的访问路径是http://localhost:8080/struts2_day01/hello.action
<package name="default" namespace="/" extends="struts-default">
<action name="hello" class="cn.itcast.action.HelloAction">
<result>
/success.jsp
</result>
</action>
</package>
下面演示命名空间为/xxx/ooo的情况
新建Action类Hello1Aciton
public class Hello1Action extends ActionSupport {
private static final long serialVersionUID = 1L;
@Override
public String execute() throws Exception {
System.out.println("hello2请求进来了...");
return SUCCESS;
}
}
自定义一个包,名叫default1,命名空间是/xxx/ooo,把Hello1这个Action配置这个包下。该包下hello1这个action的访问路径是http://localhost:8080/struts2_day01/xxx/ooo/hello1.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>
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="hello" class="cn.itcast.action.HelloAction">
<result>
/success.jsp
</result>
</action>
</package>
<package name="default1" namespace="/xxx/ooo" extends="struts-default">
<action name="hello1" class="cn.itcast.action.Hello1Action">
<result>
/success.jsp
</result>
</action>
</package>
</struts>
命名空间使用公式:http://服务器ip地址/项目名/命名空间/action名字
命名空间一般是以模块名来命名,例如:部门模块 /dept 员工模块 /emp
action标签
作用:
配置Action类。
属性:
-
name:指定的Action类的访问名称。注意此处不能有后缀。必须唯一。
-
class:指定的是Action类的全限定类名。
-
method:指定的是Action中方法名称
每新建一个Action类,都要为该类做配置:
<package name="default" namespace="/" extends="struts-default">
<action name="hello" class="cn.itcast.action.HelloAction">
<result>
/success.jsp
</result>
</action>
</package>
特殊情况:
如果在配置action节点时,没有指定class属性,则默认寻找com.opensymphony.xwork2.ActionSupport类,因为在struts-default.xml做了如下配置,指定默认的Action类,当根据某个名字找不到对应的action时,就找默认的类ActionSupport.
通过查看ActionSupport类的源码发现,里面提供了一个execute方法,请求进入ActionSupport,执行默认的execute方法,execut方法的返回值是success,所以就会寻找success这个结果集,最终完成页面跳转。
示例代码:
在struts.xml中新增一个action节点的配置,name叫hello1,不指定class属性
<?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>
<!-- 自定义常量 -->
<!-- 开启开发者模式 -->
<constant name="struts.devMode" value="true"></constant>
<!-- namespace:限定该包下Action的访问路径 -->
<package name="default" namespace="/" extends="struts-default">
<!-- 当找不到对应的action时,就找默认的action -->
<default-action-ref name="hello"></default-action-ref>
<!--
name:Action类的名字,具有唯一性,页面上通过name来访问Action类
-->
<action name="hello" class="cn.itcast.action.HelloAction">
<!-- 配置结果集 :name属性的值一定要与execute方法的返回值一致-->
<!-- name属性的默认值就是success -->
<result>
/success.jsp
</result>
<result name="fail">
/fail.jsp
</result>
</action>
<!-- 没有指定class属性,就找ActionSupport,执行execute方法 -->
<action name="hello1">
<result name="success">
/success.jsp
</result>
</action>
</package>
在浏览器地址栏中输入地址:http://localhost:8080/struts2_day01/hello1.action,发现依然能跳转到success.jsp页面,证明请求进入了ActionSupport.
如果根据名字不到对应的action,则默认使用指定的action的名字。当访问hello123时,在包中根本没有名叫hello123的类,但也能跳转到success.jsp页面,因为会去找hello,执行HelloAction类的execute方法
示例代码:
在struts.xml中添加节点,指定当某个action的名字不存在时,默认找哪个action
<!-- 自定义常量 -->
<!-- 开启开发者模式 -->
<constant name="struts.devMode" value="true"></constant>
<!-- namespace:限定该包下Action的访问路径 -->
<package name="default" namespace="/" extends="struts-default">
<!-- 当找不到对应的action时,就找默认的action -->
<default-action-ref name="hello"></default-action-ref>
<!--
name:Action类的名字,具有唯一性,页面上通过name来访问Action类
-->
<action name="hello" class="cn.itcast.action.HelloAction">
<!-- 配置结果集 :name属性的值一定要与execute方法的返回值一致-->
<!-- name属性的默认值就是success -->
<result>
/success.jsp
</result>
<result name="fail">
/fail.jsp
</result>
</action>
<!-- 不指定class,默认找ActionSupport类 -->
<action name="test1">
<result name="success">
/success.jsp
</result>
</action>
</package>
在浏览器中输入http://localhost:8080/struts2_day01/hello123.action,发现依然能跳转到success.jsp页面,证明生效了。
Action的编写和调用访问
明确:Struts2是一个MVC框架,C是核心过滤器Filter,V是JSP(Html),M是Action。
Action编写方式(3种)
实现Action接口(了解)
好处:可以利用Action接口里的静态常量作为方法的返回值(对应的是结果集的名字)
案例:自定义Action类Test2Action,实现Action接口
public class Test2Action implements Action{
@Override
public String execute() throws Exception {
System.out.println("test2请求进来了");
// return "success";
return SUCCESS;
}
}
在struts.xml中配置Test2Action类
<?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>
<!-- 自定义常量 -->
<!-- 开启开发者模式 -->
<constant name="struts.devMode" value="true"></constant>
<!-- 允许动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<!-- namespace:限定该包下Action的访问路径 -->
<package name="default" namespace="/" extends="struts-default">
<!-- 当找不到对应的action时,就找默认的action -->
<default-action-ref name="hello"></default-action-ref>
<!--
name:Action类的名字,具有唯一性,页面上通过name来访问Action类
-->
<action name="hello" class="cn.itcast.action.HelloAction">
<!-- 配置结果集 :name属性的值一定要与execute方法的返回值一致-->
<!-- name属性的默认值就是success -->
<result>
/success.jsp
</result>
<result name="fail">
/fail.jsp
</result>
</action>
<!-- 不指定class,默认找ActionSupport类 -->
<action name="test1">
<result name="success">
/success.jsp
</result>
</action>
<action name="test2" class="cn.itcast.action.Test2Action">
<result name="success">
/test2.jsp
</result>
</action>
</package>
新建test2.jsp. 在浏览器中输入地址:http://localhost:8080/struts2_day01/test2.action测试访问 注:当execute方法的返回值是NONE时,不需要为该action配置结果集,也就是不做任何页面跳转.
public class Test2Action implements Action{
@Override
public String execute() throws Exception {
System.out.println("test2请求进来了");
// return "success";
// return SUCCESS;
//如果返回NONE,不做页面跳转
return NONE;
}
修改struts.xml配置,在test2的action节点下,不需要配置结果集
<action name="test2" class="cn.itcast.action.Test2Action">
<!-- <result>
/test1.jsp
</result> -->
</action>
继承ActionSupport父类,重写execute方法(重点)
本质上与第一种方式一样,因为ActionSupport已经实现了Action接口。
好处:可以利用Action接口里的常量,也可以利用父类里的国际化、校验、添加错误信息方法。
查看ActionSupport的源码,我们发现,里面有很多有用的方法,子类是可以直接用的。
写一个POJO类,在类里提供execute方法(了解)
什么是POJO:Plain Ordinary Java Object,意为简单Java对象。
在自定义的POJO类中编写execute方法需要满足以下条件:
- 修饰符为public
- 返回类型为String
- 方法名叫execute
- 无形参
- 异常可选
特征:没有现成的东西可用
案例:写一个POJO类来充当Action,一定要在类里边提供一个execute方法
public class Test3Action{
public String execute(){
System.out.println("test3请求进来了");
return "none";
}
}
在struts.xml中配置Test3Action
总结:推荐使用第二种
Action的方法编写和调用执行
问题:用户模块有用户的新增、用户的查询、用户的删除、用户的修改,需要编写4个Action类,为每个Action类在struts.xml作配置.需要编写很多个Action类,struts.xml配置文件很庞大。
可以这样来解决:
在Action类里编写多个方法,每个请求都会执行该Action类里对应的方法,这样,减少Action类的个数,降低struts.xml文件的配置量。
Action的方法编写格式
在Action中自定义方法,需要满足一下特征:
- 修饰符为public
- 返回类型为String
- 无形参
- 异常可选
通过设置method属性调用Action中的方法
案例:新建DeptAction类
public class DeptAction extends ActionSupport{
public String add(){
System.out.println("部门新增");
return NONE;
}
public String list(){
System.out.println("部门查询");
return NONE;
}
public String update(){
System.out.println("部门修改");
return NONE;
}
public String delete(){
System.out.println("部门删除");
return NONE;
}
}
在struts.xml配置DepgAction
<!-- 通过method属性指定执行哪个方法 -->
<action name="addDept" class="cn.itcast.action.DeptAction" method="add"></action>
<action name="listDept" class="cn.itcast.action.DeptAction" method="list"></action>
<action name="updateDept" class="cn.itcast.action.DeptAction" method="update"></action>
<action name="deleteDept" class="cn.itcast.action.DeptAction" method="delete"></action>
在浏览器中测试访问:
- 部门新增:http://localhost:8080/struts2_day01/add.action
- 部门查询:http://localhost:8080/struts2_day01/list.action
- 部门修改:http://localhost:8080/struts2_day01/update.action
- 部门删除:http://localhost:8080/struts2_day01/delete.action
通配符的使用
在struts2中用表示通配符:匹配所有路径,{1}取出第一个的值,{2}取出第二个*的值.
修改struts.xml,把四行配置改成一行配置的写法
<!-- <action name="addDept" class="cn.itcast.action.DeptAction" method="add"></action>
<action name="listDept" class="cn.itcast.action.DeptAction" method="list"></action>
<action name="updateDept" class="cn.itcast.action.DeptAction" method="update"></action>
<action name="deleteDept" class="cn.itcast.action.DeptAction" method="delete"></action> -->
<!-- *匹配任意的路径 {1}表示第一个*的值 -->
测试
- 输入:http://localhost:800/struts2_day01/add.action 执行DeptAction中的add方法
- 输入:http://localhost:8080/struts2_day01/list.action
执行DeptAction中的list方法 - 输入:http://localhost:800/struts2_day01/update.action
执行DeptAction中的update方法 - 输入:http://localhost:800/struts2_day01/delete.action
执行DeptAction中的delete方法
有两个通配符的情况
新建EmployeeAction类
public class EmployeeAction extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
public String add(){
System.out.println("员工新增");
return NONE;
}
public String list(){
System.out.println("员工查询");
return NONE;
}
public String update(){
System.out.println("员工修改");
return NONE;
}
public String delete(){
System.out.println("员工删除");
return NONE;
}
}
修改struts.xml文件,换成两个*的写法
<!-- 匹配像Dept_add这样的路径 -->
<action name="*_*" class="cn.itcast.action.{1}Action" method="{2}"></action>
测试
- 输入:http://localhost:800/bk_struts2_day01/Dept_add.action
执行DeptAction中的add方法 - 输入:http://localhost:800/bk_struts2_day01/Dept_list.action
执行DeptAction中的list方法 - 输入:http://localhost:800/bk_struts2_day01/Employee_update.action
执行EmployeeAction中的update方法 - 输入:http://localhost:800/bk_struts2_day01/Employee_delete.action
执行EmployeeAction中的delete方法
注意:当有多个带有通配符的名字与Url匹配时,优先匹配前面的,后面的就不匹配了。
当像下面这样写时,访问Employee_add时会报错,因为Employee_add优先匹配*
<!-- *匹配任意的路径 {1}取出第一个*的值 -->
<action name="*" class="cn.itcast.action.DeptAction" method="{1}"></action>
<!-- 匹配像add_Job这样的路径 -->
<action name="*_*" class="cn.itcast.action.{1}Action" method="{2}"></action>
动态方法调用
作用:允许通过action名字!方法名来访问Action类中的方法。
需要把把动态方法调用的开关打开,默认是关闭的。
<!-- 允许动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
案例:新建Action类Test4Action
public class Test4Action extends ActionSupport{
private static final long serialVersionUID = 1L;
public String method(){
System.out.println("test4请求进来了");
return NONE;
}
}
在struts.xml配置Test4Action
<action name="test4" class="cn.itcast.action.Test4Action"></action>
输入地址访问:http://localhost:8080/bk_struts2_day01/test4!method.action执行method方法,感叹号后跟的是方法名,指定执行method方法。
缺点:不安全,不推荐使用。