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. python:字符串的连接

    python中有很多字符串连接方式,今天在写代码,顺便总结一下: 最原始的字符串连接方式:str1 + str2 python 新字符串连接语法:str1, str2 奇怪的字符串方式:str1 st ...

  2. 各种常用的CDN加速服务

    各种CDN加速网址:点击此处 1.Echar <script type="text/javascript" src="http://echarts.baidu.co ...

  3. iOS UITableViewDelegate && UITableViewDataSource 执行顺序

    #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableV ...

  4. python中executemany的使用

    conn = MySQLdb.connect(host = “localhost”, user = “root”, passwd = “password”, db = “myDB”, charset= ...

  5. Hibernate学习三----------session详解

    © 版权声明:本文为博主原创文章,转载请注明出处 如何获取session对象 1. openSession 2. getCurrentSession - 如果使用getCurrentSession需要 ...

  6. 开发ActiveX控件调用另一个ActiveX系列0——身份证识别仪驱动的问题

    程序员要从0下表开始,这篇是介绍这个系列的背景的,没有兴趣的人可以直接跳过. 为什么要开发ActiveX控件 由于工作需要,我们开发了一个网站,使用了一款身份证识别仪的网页ActiveX(OCX)插件 ...

  7. mBot试用体验

    [Arduino话题] [mBot试用体验]1.mBot开箱体验(部分资料合集)http://bbs.elecfans.com/forum.php?mod=viewthread&tid=532 ...

  8. rtems 4.11 工具链

    4年前,曾经把rtems4.10移植到atmel 9263上,要不是当时移植的git仓库还在的话,真是不相信自己居然还干过这事.所以这次再捡起的时候,要记录一下.还是从编译器开始. 首先打开 http ...

  9. u-boot-2014.04分析

    本文档以smdk2410为例初步分析了u-boot-2014.04的配置.启动流程.代码重定向.内存分布. u-boot-2014.04这个版本的uboot从Linux内核中借鉴了很多东西,比如编译u ...

  10. 用array_search 数组中查找是否存在这个 值

    #判读里面是否还有id=1的超级管理员 $key=array_search(1, $ids); #判读这个是否存在 if($key!==FALSE){ #如果存在就unset掉这个 unset($id ...