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:

  

    通配符映射示例(1):<br/>
    <a href="${pageContext.request.contextPath }/pattern/a_add.do">通配符示例(1)</a><br/>
    <a href="${pageContext.request.contextPath }/pattern/b_add.do">通配符示例(1)</a><br/>
    <a href="${pageContext.request.contextPath }/pattern/c_add.do">通配符示例(1)</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名了,结果也有变化)

    通配符映射示例(2):<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配置可以改写
                {1}:表示匹配通配符匹配的第一个字符串
            这个action会与前面的name为*_add的冲突
        -->
        <action name="*_add" class="cn.itcast.pattern.{1}" method="add">
            <result name="success">/pattern/success.jsp</result>
            <result name="add">/pattern/{1}.jsp</result>
        </action><!--
        

需求3:前面的基础上,方法也有变化

    通配符映射示例(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>

通配符方式:

<!-- 以上的配置可以改成 -->
        <!--
            {2}匹配的就是*通配符匹配的第二个子串
            {0}匹配的是通配符的整个串
        -->
        <action name="*_*" class="cn.itcast.pattern.{1}" method="{2}">
            <result name="success">/pattern/success.jsp</result>
            <result name="add">/pattern/{1}.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="0">
    <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/>

    通配符映射示例(1):<br/>
    <a href="${pageContext.request.contextPath }/pattern/a_add.do">通配符示例(1)</a><br/>
    <a href="${pageContext.request.contextPath }/pattern/b_add.do">通配符示例(1)</a><br/>
    <a href="${pageContext.request.contextPath }/pattern/c_add.do">通配符示例(1)</a><br/>
    <br/>
    <br/>

    通配符映射示例(2):<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/>
    通配符映射示例(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/>
    动态方法调用示例:<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/>
    通配符示例(4):<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配置可以改写
                {1}:表示匹配通配符匹配的第一个字符串
            这个action会与前面的name为*_add的冲突
        -->
        <action name="*_add" class="cn.itcast.pattern.{1}" method="add">
            <result name="success">/pattern/success.jsp</result>
            <result name="add">/pattern/{1}.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>

        -->
        <!-- 以上的配置可以改成 -->
        <!--
            {2}匹配的就是*通配符匹配的第二个子串
            {0}匹配的是通配符的整个串
        -->
        <action name="*_*" class="cn.itcast.pattern.{1}" method="{2}">
            <result name="success">/pattern/success.jsp</result>
            <result name="add">/pattern/{1}.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

  

时间: 2024-10-11 09:07:12

struts2的通配符与动态方法调用的相关文章

struts2的通配符和动态方法调用

<?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>    <

Struts2系列:(7)通配符和动态方法调用

当前存在的问题:在struts.xml配置文件中,每个action标签对应一个类中的方法.但是,在实际JavaWeb项目开发中,有许多继承自ActionSupport类的类(其中也包括很多方法),如果每个方法对应一个action标签,那么就会造成struts.xml非常庞大. 本节中介绍的通配符 和 动态方法调用 就是为了解决这一问题.本节分成2个部分:(1)通配符映射 和 (2)动态调用 概念:Struts应用可能有很多action 声明,可把多个相似的映射关系简化为一个(通用)映射关系的机制

struts2.5动态方法调用和默认Action

在动态方法调用中,使用通配符方法出现问题,参考了http://www.cnblogs.com/jasonlixuetao/p/5933671.html 这篇博客,问题解决了. 这个是helloworld.xml: 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Co

struts2中通配符和DMI(动态方法调用)

在struts2中不建议使用Dynamic Method Invocation,具体原因见官方文档: http://struts.apache.org/docs/action-configuration.html#ActionConfiguration-WildcardMethod; 刚刚接触这块,所以两种方法各自实现一下: 1)动态方法调用: struts.xml文件: <package name="default" namespace="/yin" ext

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

一.Struts2执行过程图: 二.struts2配置文件的加载顺序 struts-default.xml---struts-plugin.xml---struts.xml 具体步骤: 三.Action中动态方法调用<Dynamic Method Invocation> DMI 第一种方式: 自定义DMIAction类,使它继承ActionSupport类,该类无需手动重写execute(),底层有默认实现.因此我们也可以自定义方法list. struts.xml中的action元素植入met

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

01.Struts 2基本结构 使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问ServletAPI时实现用户会话跟踪,其简单的程序运行流程图如下 Struts2框架是基于MVC模式.基于MVC模式框架的核心就是控制器对所有请求进行统一处理.Struts2的控制器StrutsPrepareAndExecuteFilter由ServletAPI中的Filter充当,当web容器的接收到登录

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

动态方法调用 1.Struts2默认关闭DMI功能,需要使用需要手动打开,配置常量 [html] view plain copy struts.enable.DynamicMethodInvocation = true 2.使用“!”方法,即action名称!方法名称. struts.xml [html] view plain copy <action name="query" class="action.QueryAction"> <result

Struts2.5动态方法调用action和使用通配符访问action

[原帖地址]http://blog.csdn.net/leafage_m/article/details/54577687 动态方法调用Action. 这种方法,需要在struts.xml中对其进行支持: [html] view plain copy print? <!-- 是否开启动态方法调用 --> <constant name="struts.enable.DynamicMethodInvocation" value="true" />

Struts2动态方法调用(DMI)

在Struts2中动态方法调用有三种方式,动态方法调用就是为了解决一个Action对应多个请求的处理,以免Action太多 第一种方式:指定method属性这种方式我们前面已经用到过,类似下面的配置就可以实现 <action name="chainAction" class="chapter2.action.Chapter2Action" method="chainAction"> <result name="chai