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. Android常用资源

    Eclipse ADT http://developer.android.com/sdk/installing/installing-adt.html https://dl-ssl.google.co ...

  2. POJ 3373 Changing Digits

    题目大意: 给出一个数n,求m,使得m的长度和n相等.能被k整除.有多个数符合条件输出与n在每位数字上改变次数最小的.改变次数同样的输出大小最小的.  共同拥有两种解法:DP解法,记忆化搜索的算法. ...

  3. dm8148 videoM3 link源代码解析

    样例:从A8送一帧jpeg图片到videoM3解码,然后在将解码的数据传递到A8, 这个流程涉及的link源代码例如以下: dm8148 link之间数据传递 1)在A8上调用IpcBitsOutLi ...

  4. 38: 立方根getCubeRoot

    题目描述:计算一个数字的立方根,不使用库函数 •接口说明 原型:public static double getCubeRoot(double input) 输入:double 待求解参数 返回值:d ...

  5. Ajax请求的跨域(CORS)问题

    用浏览器,通过XHR(XMLHttpRequest)请求向另外一个域名请求数据时.会碰到跨域(CORS)问题. CORS:Cross-Origin Resource Sharing 什么是跨域? 简单 ...

  6. 《C专家编程》数组和指针并不同--多维数组

    <C专家编程>数组和指针并不同 标签(空格分隔): 程序设计论著笔记 1. 背景理解 1.1 区分定义与声明 p83 声明相当于普通声明:它所说明的并不是自身,而是描写叙述其它地方创建的对 ...

  7. thymeleaf模版的使用

    thymeleaf,我个人认为是个比较好的模板,性能也比一般的,比如freemaker的要高,而且把将美工和程序员能够结合起来,美工能够在浏览器中查看静态效果,程序员可以在应用服务器查看带数据的效果. ...

  8. 使用OpenGL进行Mandelbrot集的可视化

    Mandelbrot集是哪一集?? Mandelbrot集不是哪一集!! 啊不对-- Mandelbrot集是哪一集!! 好像也不对-- Mandelbrot集是数集!! 所以--他不是一集而是数集? ...

  9. Spark源码分析之二:Job的调度模型与运行反馈

    在<Spark源码分析之Job提交运行总流程概述>一文中,我们提到了,Job提交与运行的第一阶段Stage划分与提交,可以分为三个阶段: 1.Job的调度模型与运行反馈: 2.Stage划 ...

  10. Java各类格式转换

    1.Java 根据固定格式的Excel生成实体类 2.GPS 经纬度转换为 经过旋转后的平面坐标