struts2的通配符与动态方法调用
1、Action标签中的method属性
我们知道action默认的执行的方法是execute方法,但是一个action只执行一个方法我们觉得有点浪费,我们希望在一个action中实现同一模块的不同功能。怎么办呢?
思考:
我们是否可以在execute()方法中添加一个判断,然后根据该判断选择我们执行的方法呢?我想struts2也是这样干的。不过是在execute之前的方法中进行的,判断的依据不是通过参数,而是通过取读配置文件或者其他得到的。
Struts2在Action中为我们提供了这样的一个属性:method,使用method属性可以指定我们希望执行的自定义方法。
<!--
struts2框架运行时,默认执行action类中的execute方法
在action标签里面的method属性:指定的是要执行的action类中的哪个方法
-->
<!--<action name="bookAction" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action>
我们的自定义方法有什么规范吗?
例子:
/*
*自定义方法
* 由public来修饰
* 必须是String返回类型
* 不能传参数
* 方法名自定义
* 总之,一句话:除了方法名与execute()不一样,其他所有的内容都一样
*/
public String add() throws Exception{
System.out.println("bookAction ****** add");
return "add";
}
2、通配符的使用
我们又发现,当多个action都指向同一个action的某一个方法的时候,我们就需要定义好多action,但这些action的代码几乎一致。这时候,我们想?应该如何优化呢。
Struts2中提供了一种解决工具,通配符”*”.
简单例子:
需求1:
通配符映射示例():<br/>
<a href="${pageContext.request.contextPath }/pattern/a_add.do">通配符示例()</a><br/>
<a href="${pageContext.request.contextPath }/pattern/b_add.do">通配符示例()</a><br/>
<a href="${pageContext.request.contextPath }/pattern/c_add.do">通配符示例()</a><br/>
<br/>
<br/>
原方案:
<action name="a_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action>
<action name="b_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action>
<action name="c_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action>
通配符方式:
<!--
*,就是通配符,匹配的是不一样的内容,表示任意一字符串
-->
<!--<action name="*_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action>
需求2:(这里不同点不仅仅是Action名了,结果也有变化)
通配符映射示例():<br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction_add.do">图书</a><br/>
<a href="${pageContext.request.contextPath }/pattern/UserAction_add.do">用户</a><br/>
<br/>
<br/>
原方案:
<!--<action name="BookAction_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action> <action name="UserAction_add" class="cn.itcast.pattern.UserAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/UserAction.jsp</result>
</action>
通配符方式:
<!--
以上的两个Action配置可以改写
{}:表示匹配通配符匹配的第一个字符串
这个action会与前面的name为*_add的冲突
-->
<action name="*_add" class="cn.itcast.pattern.{1}" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/{}.jsp</result>
</action><!--
需求3:前面的基础上,方法也有变化
通配符映射示例():<br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction_add.do">图书添加</a><br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction_delete.do">图书删除</a><br/>
<br/>
<br/>
<a href="${pageContext.request.contextPath }/pattern/UserAction_add.do">用户添加</a><br/>
<a href="${pageContext.request.contextPath }/pattern/UserAction_delete.do">用户删除</a><br/>
<br/>
<br/>
原方案:
<action name="BookAction_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="add">/pattern/BookAction.jsp</result>
</action>
<action name="BookAction_delete" class="cn.itcast.pattern.BookAction" method="delete">
<result name="success">/pattern/success.jsp</result>
</action>
<action name="UserAction_add" class="cn.itcast.pattern.UserAction" method="add">
<result name="add">/pattern/UserAction.jsp</result>
</action>
<action name="UserAction_delete" class="cn.itcast.pattern.UserAction" method="delete">
<result name="success">/pattern/success.jsp</result>
</action>
通配符方式:
<!-- 以上的配置可以改成 -->
<!--
{}匹配的就是*通配符匹配的第二个子串
{}匹配的是通配符的整个串
-->
<action name="*_*" class="cn.itcast.pattern.{1}" method="{2}">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/{}.jsp</result>
</action>
Ok,总结一下:
“*”是struts2中的通配符
{1},{2}…等分别代表通配符匹配的第n个字符串
其实{0}这种写法也存在,比嗾使所有通配符匹配的字符串的拼接
3、动态方法调用
我们前面使用通配符的方式可以通过链接调用同一个action的不同方法,其实struts2还有一种方式可以达到前面的效果,那就是动态方法调用。
如何执行动态方法调用?
首先,对链接的url有要求。例如:
动态方法调用示例:<br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction!add.do">图书添加</a><br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction!delete.do">图书删除</a><br/>
<br/>
<br/>
格式为…./namespace+actionName+!+methodName
对应的action:
<!--
动态方法调用:
页面中请求连接:namespace+actionName+"!"+执行方法名
在struts.xml文件中,不用配置method属性,而是通过页面的链接动态执行指定方法
动态方法调用,不经常使用,经常使用的是通配符
动态方法调用,默认是开启状态
关闭 动态方法调用 :
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
-->
<action name="BookAction" class="cn.itcast.pattern.BookAction">
<result name="add">/pattern/BookAction.jsp</result>
</action>
4、全局result
前面的例子可以发现,我们的result name=”success”执行的代码都是一样的,那么为什么我们不可以将它封装起来呢?一劳永逸。
Struts2中提供了一个标签:<global-result>,它可以设置全包的结果类型
例子:
<!-- 我们在这里的result中的name=success多次调用,都是同样的结果,我们希望一劳永逸,可以在package下配置全局结果 -->
<!-- 配置全局结果类型,当然如果action中配置了优先执行action中的 -->
<!--
局部结果类型和全局结果类型的作用范围:
局部的:作用于某个action
全局的:作用于某个package
-->
<global-results>
<result name="success">/pattern/successGlobal.jsp</result>
</global-results>
5、action的一个小特点:多实例,线程安全
这个只是简单了解一下,我们可以在action中重写一下无参构造,可以发现,每一次调用该action,都会执行该action中构造方法的内容
上面用的部分素材:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'test.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
访问BookAction_add测试action标签中的method属性<br/>
<a href="${pageContext.request.contextPath }/pattern/bookAction.do">测试</a><br/>
<br/>
<br/> 通配符映射示例():<br/>
<a href="${pageContext.request.contextPath }/pattern/a_add.do">通配符示例()</a><br/>
<a href="${pageContext.request.contextPath }/pattern/b_add.do">通配符示例()</a><br/>
<a href="${pageContext.request.contextPath }/pattern/c_add.do">通配符示例()</a><br/>
<br/>
<br/> 通配符映射示例():<br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction_add.do">图书</a><br/>
<a href="${pageContext.request.contextPath }/pattern/UserAction_add.do">用户</a><br/>
<br/>
<br/>
通配符映射示例():<br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction_add.do">图书添加</a><br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction_delete.do">图书删除</a><br/>
<br/>
<br/>
<a href="${pageContext.request.contextPath }/pattern/UserAction_add.do">用户添加</a><br/>
<a href="${pageContext.request.contextPath }/pattern/UserAction_delete.do">用户删除</a><br/>
<br/>
<br/>
动态方法调用示例:<br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction!add.do">图书添加</a><br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction!delete.do">图书删除</a><br/>
<br/>
<br/>
通配符示例():<br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction_add.do">图书添加</a><br/>
<a href="${pageContext.request.contextPath }/pattern/BookAction_delete.do">图书删除</a><br/>
<br/>
<br/>
全局result:<br/>
<a href="${pageContext.request.contextPath}/pattern/BookAction_find.do">图书查找</a><br/> </body>
</html>
test.jsp
package cn.itcast.pattern; import com.opensymphony.xwork2.ActionSupport; public class BookAction extends ActionSupport { @Override
public String execute() throws Exception {
System.out.println("bookAction ****** execute");
return "success";
}
/*
* 在struts2框架中,action是多实例的
*/
public BookAction(){
System.out.println("bookAction 的构造方法");
}
/*
*自定义方法
* 由public来修饰
* 必须是String返回类型
* 不能传参数
* 方法名自定义
* 总之,一句话:除了方法名与execute()不一样,其他所有的内容都一样
*/
public String add() throws Exception{
System.out.println("bookAction ****** add");
return "add";
} public String delete() throws Exception{
System.out.println("bookAction ****** delete");
return "success";
} public String find() throws Exception{
System.out.println("bookAction ****** find");
return "success";
} public String update() throws Exception{
return "success";
}
}
BookAction.java
<?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="pattern" namespace="/pattern" extends="struts-default"> <!-- 我们在这里的result中的name=success多次调用,都是同样的结果,我们希望一劳永逸,可以在package下配置全局结果 -->
<!-- 配置全局结果类型,当然如果action中配置了优先执行action中的 -->
<!--
局部结果类型和全局结果类型的作用范围:
局部的:作用于某个action
全局的:作用于某个package
-->
<global-results>
<result name="success">/pattern/successGlobal.jsp</result>
</global-results> <!--
struts2框架运行时,默认执行action类中的execute方法
在action标签里面的method属性:指定的是要执行的action类中的哪个方法
-->
<!--<action name="bookAction" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action> <action name="a_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action>
<action name="b_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action>
<action name="c_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action> -->
<!-- 以上的配置可以改写如下: -->
<!--
*,就是通配符,匹配的是不一样的内容,表示任意一字符串
-->
<!--<action name="*_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action> --> <!--<action name="BookAction_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/BookAction.jsp</result>
</action> <action name="UserAction_add" class="cn.itcast.pattern.UserAction" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/UserAction.jsp</result>
</action> -->
<!--
以上的两个Action配置可以改写
{}:表示匹配通配符匹配的第一个字符串
这个action会与前面的name为*_add的冲突
-->
<action name="*_add" class="cn.itcast.pattern.{1}" method="add">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/{}.jsp</result>
</action><!-- <action name="BookAction_add" class="cn.itcast.pattern.BookAction" method="add">
<result name="add">/pattern/BookAction.jsp</result>
</action>
<action name="BookAction_delete" class="cn.itcast.pattern.BookAction" method="delete">
<result name="success">/pattern/success.jsp</result>
</action>
<action name="UserAction_add" class="cn.itcast.pattern.UserAction" method="add">
<result name="add">/pattern/UserAction.jsp</result>
</action>
<action name="UserAction_delete" class="cn.itcast.pattern.UserAction" method="delete">
<result name="success">/pattern/success.jsp</result>
</action> -->
<!-- 以上的配置可以改成 -->
<!--
{}匹配的就是*通配符匹配的第二个子串
{}匹配的是通配符的整个串
-->
<action name="*_*" class="cn.itcast.pattern.{1}" method="{2}">
<result name="success">/pattern/success.jsp</result>
<result name="add">/pattern/{}.jsp</result>
</action> <!--
动态方法调用:
页面中请求连接:namespace+actionName+"!"+执行方法名
在struts.xml文件中,不用配置method属性,而是通过页面的链接动态执行指定方法
动态方法调用,不经常使用,经常使用的是通配符
动态方法调用,默认是开启状态
关闭 动态方法调用 :
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
-->
<action name="BookAction" class="cn.itcast.pattern.BookAction">
<result name="add">/pattern/BookAction.jsp</result>
</action> <action name="BookAction_find" class="cn.itcast.pattern.BookAction" method="find">
</action> </package> </struts>
struts_pattern.xml
struts2的通配符与动态方法调用的更多相关文章
- Struts2笔记——通配符和动态方法调用
通配符映射 * 一个 Web应用可能有成百上千个 action 声明. 可以利用 struts提供的通配符映射机制把多个彼此相似的映射关系简化为一个映射关系 * 通配符映射规则 > 若 ...
- Struts2 2.5版本的通配符和动态方法调用的问题
Struts2.5版本之后,使用通配符的时候出现错误 配置的四个action,使用通配符和动态方法的时候找不到其中的update方法后来经过查找才知道原来是版本加了一个 <action name ...
- Struts2学习第二天——动态方法调用
method属性 在前面的例子里,Action默认使用execute()方法来处理请求.但是,如果有多个不同的请求需要同一个Action进行不同处理,怎么办?在Struts.xml文件中,需要指定Ac ...
- Struts2.5.12中动态方法调用问题
使用版本:struts-2.5.12-all 出现问题:在开启动态方法调用后,找不到没有匹配的路径映射 <constant name="struts.enable.DynamicMet ...
- 第三章Struts2 Action中动态方法调用、通配符的使用
01.Struts 2基本结构 使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问Servl ...
- Struts2 Action中动态方法调用、通配符的使用
一.Struts2执行过程图: 二.struts2配置文件的加载顺序 struts-default.xml---struts-plugin.xml---struts.xml 具体步骤: 三.Actio ...
- struts2的动态方法调用(DMI)和通配符映射
动态方法调用 1.Struts2默认关闭DMI功能,需要使用需要手动打开,配置常量 struts.enable.DynamicMethodInvocation = true 2.使用“!”方法,即 ...
- Struts2学习笔记 - Action篇<动态方法调用>
有三种方法可以使一个Action处理多个请求 动态方法调用DMI 定义逻辑Acton 在配置文件中使用通配符 这里就说一下Dynamic Method nvocation ,动态方法调用,什么是动态方 ...
- Struts2 动态方法调用
01.Struts 2基本结构 使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问Servl ...
随机推荐
- Swift初窥----语法进阶
缺省绑定(Optional Binding 自己主动置空) 通过在类型变量后,加上?,能够实现缺省绑定为nil var window: UIWindow? 就是说,假设不正确window赋值,则win ...
- hint指定index的深入理解
http://czmmiao.iteye.com/blog/1480247创建一个表,含有位图index和b-tree index SQL> create table t as select o ...
- 邮箱大师WPZ协议包
WIRELESS Z PACKET: i8-version(WZPUnit.getVersion() & 3 | WZPUnit.MAGIC_MASK = 1 & 3 | -48 = ...
- 在tomcat中用jndi配置数据源启动java web程序
1.在web.xml中添加: <resource-ref> <res-ref-name>jdbc/MTSDB</res-ref-name> <re ...
- Spring配置错误记录
很多其它Spring问题因为发生时未记录而遗忘了~~~~~~~ 如今动动手 解决方式因为不是源头分析因而仅供參考.! ! 严重: Exception sending context destroyed ...
- linux中MACHINE_START&END在9g10ek上实现
在linux的板卡初始化文件中有machine的相关定义 //arch/arm/mach-at91/board-sam9261ek.c MACHINE_START(AT91SAM9G10EK, &qu ...
- java 单例模式(转载)
http://www.cnblogs.com/whgw/archive/2011/10/05/2199535.html Java中单例模式是一种常见的设计模式,可分为三种:懒汉式单例.饿汉式单例.登记 ...
- cocos2d-x AssetsManager libcurl使用心得
libcurl使用心得 最新正在写cocosclient更新的逻辑.研究了一下cocos2d-x自带的Libcurl,下面是自己在使用过程中的心得和遇到的未解问题.希望大家一起讨论一下,欢迎大家指导. ...
- 手动删除引用nuget如何还原
1.不小心从项目的引用中删除了nuget安装的程序集; 2.从其他地方复制的packages.config到当前项目; 这两种情况 在解决方案中是无法通过还原nuget来还原程序集的,可以通过以下的方 ...
- 【BZOJ1124】[POI2008]枪战Maf 贪心+思路题
[BZOJ1124][POI2008]枪战Maf Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开 ...