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的通配符与动态方法调用的更多相关文章

  1. Struts2笔记——通配符和动态方法调用

     通配符映射 * 一个 Web应用可能有成百上千个 action 声明. 可以利用 struts提供的通配符映射机制把多个彼此相似的映射关系简化为一个映射关系 * 通配符映射规则     > 若 ...

  2. Struts2 2.5版本的通配符和动态方法调用的问题

    Struts2.5版本之后,使用通配符的时候出现错误 配置的四个action,使用通配符和动态方法的时候找不到其中的update方法后来经过查找才知道原来是版本加了一个 <action name ...

  3. Struts2学习第二天——动态方法调用

    method属性 在前面的例子里,Action默认使用execute()方法来处理请求.但是,如果有多个不同的请求需要同一个Action进行不同处理,怎么办?在Struts.xml文件中,需要指定Ac ...

  4. Struts2.5.12中动态方法调用问题

    使用版本:struts-2.5.12-all 出现问题:在开启动态方法调用后,找不到没有匹配的路径映射 <constant name="struts.enable.DynamicMet ...

  5. 第三章Struts2 Action中动态方法调用、通配符的使用

    01.Struts 2基本结构 使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问Servl ...

  6. Struts2 Action中动态方法调用、通配符的使用

    一.Struts2执行过程图: 二.struts2配置文件的加载顺序 struts-default.xml---struts-plugin.xml---struts.xml 具体步骤: 三.Actio ...

  7. struts2的动态方法调用(DMI)和通配符映射

    动态方法调用   1.Struts2默认关闭DMI功能,需要使用需要手动打开,配置常量 struts.enable.DynamicMethodInvocation = true 2.使用“!”方法,即 ...

  8. Struts2学习笔记 - Action篇<动态方法调用>

    有三种方法可以使一个Action处理多个请求 动态方法调用DMI 定义逻辑Acton 在配置文件中使用通配符 这里就说一下Dynamic Method nvocation ,动态方法调用,什么是动态方 ...

  9. Struts2 动态方法调用

    01.Struts 2基本结构 使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问Servl ...

随机推荐

  1. winform制作自定义控件

    一 .概述Windows 窗体控件是可再次使用的组件,它们封装了用户界面功能,并且可以用于客户端 Windows 应用程序.“Windows 窗体”不仅提供了许多现成控件,还提供了自行开发控件的基础结 ...

  2. .NET C#生成随机颜色,可以控制亮度,生成暗色或者亮色 基于YUV模式判断颜色明亮度

    .NET C#生成随机颜色,可以控制亮度,生成暗色或者亮色 基于YUV模式判断颜色明亮度   随机颜色在日常开发中很常用到,有时候要控制颜色明亮度,比如在白色背景网页上的随机颜色,一般要求颜色稍微暗一 ...

  3. Java 加载器

    类的加载是由类加载器完成的,类加载器包括: 根加载器( BootStrap ).扩展加载器( Extension ).系统加载器( System )和用户自定义类加载器( java.lang.Clas ...

  4. MySQL系列:innodb源代码分析之线程并发同步机制

    innodb是一个多线程并发的存储引擎,内部的读写都是用多线程来实现的,所以innodb内部实现了一个比較高效的并发同步机制. innodb并没有直接使用系统提供的锁(latch)同步结构,而是对其进 ...

  5. matlab2016b-linux版本在ubutu16.04x64上面不能打开摄像头的处理方法

    this  can  not  work.    need  find  other way.   ================================================== ...

  6. Android-Animations介绍

    一.Animations介绍 Animations是一个实现android UI界面动画效果的API,Animations提供了一系列的动画效果,可以进行旋转.缩放.淡入淡出等,这些效果可以应用在绝大 ...

  7. .net调用存储过程详解(转载)

    本文的数据库用的是sql server 连接字符串 string conn = ConfigurationManager.ConnectionStrings["NorthwindConnec ...

  8. php类中const

    常量 const 在类里面定义常量用 const 关键字,而不是通常的 define() 函数. 语法: const constant = "value"; 例子: <?ph ...

  9. k-anonymity

    k匿名(k-anonymity)是一种常用的社交网络隐私保护技术,其思想是通过人为构造一定数量与目标节点拓扑结构相同的节点来降低用户被定位的概率 [匿名]英语怎么说_在线翻译_有道词典 http:// ...

  10. ast.literal_eval(jsonStr) json格式字符串转dict 2种方式

    json.loads(jsonStr, encoding='utf-8')import ast ast.literal_eval(jsonStr)