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. Leetcode Array 11 Container With Most Water

    题目: Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, a ...

  2. JSP——Web应用

      1.EL表达式   2.jstl fmt功能说明     3.jsp 自定义标签     4.QR码————二维码等条码

  3. matlab biplot 符号的困惑

    在matlab中做Principal component Analysis 时,常要用biplot 函数来画图,表示原分量与主分量(principal component)之间的关系,以及原始观察数据 ...

  4. 【caffe】Caffe的Python接口-官方教程-00-classification-详细说明(含代码)

    00-classification 主要讲的是如何利用caffenet(与Alex-net稍稍不同的模型)对一张图片进行分类(基于imagenet的1000个类别) 先说说教程到底在哪(反正我是找了半 ...

  5. BZOJ 1002 FJOI2007 轮状病毒 递推+高精度

    题目大意:轮状病毒基定义如图.求有多少n轮状病毒 这个递推实在是不会--所以我选择了打表找规律 首先执行下面程序 #include<cstdio> #include<cstring& ...

  6. iOS上使用自定义ttf字体

    本文转载至 http://blog.csdn.net/allison162004/article/details/38777777 项目中想使用第三方的字体,在stackoverflow上查询解决办法 ...

  7. JS基础常识理解

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. python推荐系统库

    Python推荐系统库——Surprise 在Python中实现你自己的推荐系统 python-recsys:一款实现推荐系统的python库

  9. Socket 群聊功能

    1.Server端: 拥有一个存放与客户端连接对象的List<socket> 有一个客户端发信息后 遍历List 实现群发功能 代码如下: package com.socket; impo ...

  10. c#数组的count()和length的区别

    C# 数组中 Length 表示数组项的个数,是个属性. 而 Count() 也是表示项的个数,是个方法,它的值和 Length 一样.但实际上严格地说 Count() 不是数组的内容,而是 IEnu ...