这里主要以案例演示:涵盖以下知识点

1、动态方法调用:使用关键 符号 ! 进行操作   例如:/命名空间 ! 方法名

2、动态结果集:就是说,通过后台返回的结果 ${} 获取,重定向到符合预期的页面。

3、万能通配符:*_*  :第一个 * 为 类名、第二个 * 为方法名;{1}是第一个 *

4、内部方法的调用:就是说 Action 类中的 A()  调用 B()  A方法返回B()的结果集

5、跳转Action:就是说访问一个方法,根据返回的结果匹配 result中的 name 值 跳入下一个action (result type=chain)

 6、OGNL:(不过多讲述相关概念,这里以代码为核心)

值栈的内部结构分为两部分:

  第一部分:root,结构是 list 集合一般操作的都是 root 里面的数据

  第二部分:context,结构为 Map 集合

使用经历:

root 单列集合下的 前台获取的时候不需要写 #

context 双列集合  前台获取的时候需要写 #

1、往 单列集合中推送 集合类型的数据时,不能触碰到集合的引用名称。

将泛型集合推送到值栈中:

使用 <s:debug/> 标签查看 值栈的信息:

2、值栈的访问顺序为 从上往下 寻址。如有同名的属性名,则寻址离值栈顶端最近的

核心代码截取:推送到root 也就是单列集合下

使用 <s:debug/> 标签查看 值栈的信息:

3、在我们实现 Action 接口 或 继承ActionSupport 的类中的成员属性都是放在 root 单列集合下的

4、往值栈 context 推送 key那一列会有我们指定的引用名称(需要获取的时候需要 #)

 以上为可能会遇到的问题。

完整Demo展示:

 点我下载案例Demo:

 案例结构:

为演示通配符需要方法名与jsp名称一致,add.jsp 与 list.jsp 创建在 CoordinAction文件下 

POM:

 <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties> <dependencies> <!--测试JAR-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<!--javaee.jar包是支持javaweb编程的基础jar包,跟javase编程需要jre一样!-->
<dependency>
<groupId>javaee</groupId>
<artifactId>javaee-api</artifactId>
<version>5</version>
</dependency>
<!--Struts2-core核心-->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.4.1</version>
</dependency>
<!--xwork 的核心包,最主要的功能是 支持了过滤器(interceptor)。-->
<dependency>
<groupId>org.apache.struts.xwork</groupId>
<artifactId>xwork-core</artifactId>
<version>2.3.4.1</version>
</dependency> </dependencies>

CoordinAction:

package com.gdbd.action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport; import java.util.Map; /**
* @author asus
*/
public class CoordinAction extends ActionSupport { private String message;
private String mess;
  ...省略 Get Set /***
* 动态方法的调用
* @return
*/
public String list() {
this.setMessage("通过调用 add 方法拿到返回的name寻址,再次调度 Action 中的list");
return "list";
} public String add() {
this.setMessage("动态方法调度!!!!");
return "add";
} public String get() {
Map<String, Object> session = ActionContext.getContext().getSession();
if (this.message != null) {
session.put("message", "动态结果集调用成功!!!");
this.setMess("demo2");
} else {
session.put("message", "动态结果集调用失败!!!");
this.setMess("error");
}
return "get";
} /***
* 内部方法的调用
* @return
*/
public String demo1() {
Map request = (Map) ActionContext.getContext().get("request");
request.put("message", "测试数据Action内部调度!!!");
return "demo2";
} public String demo2() {
return demo1();
} }

OgnlAction:

package com.gdbd.action;

import com.gdbd.bean.UserInfo;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
import java.util.List;
import java.util.ArrayList; /**
* @author asus
*/
public class OgnlAction extends ActionSupport { private List<UserInfo> List;
  ...省略 Get Set /***
* OGNL:存储到单列集合
*/
public String demo1() {
ActionContext context = ActionContext.getContext();
//获取值栈
ValueStack valueStack = context.getValueStack();
//伪造数据
UserInfo userInfo=new UserInfo();
userInfo.setUserName("MLQ");
userInfo.setUserPwd("MLQ");
UserInfo userInfo1=new UserInfo();
userInfo1.setUserName("FKX");
userInfo1.setUserPwd("FKX");
List<UserInfo> infoList=new ArrayList<UserInfo>();
infoList.add(userInfo);
infoList.add(userInfo1);
/***
* 将数据推送到单列集合中
* 缺点:对集合类型进行操作的时候,没有办法触碰到集合的引用名称
* 例如:添加一个 泛型List<UserInfo> 集合 没有
*/
valueStack.push(userInfo);
valueStack.push(userInfo1);
valueStack.push(infoList);
return "demo1";
}
/***
* OGNL:存储到双列集合
*/
public String demo2() {
ActionContext context = ActionContext.getContext();
//获取值栈
ValueStack valueStack = context.getValueStack();
//伪造数据
UserInfo userInfo=new UserInfo();
userInfo.setUserName("MLQ");
userInfo.setUserPwd("MLQ");
UserInfo userInfo1=new UserInfo();
userInfo1.setUserName("FKX");
userInfo1.setUserPwd("FKX");
List<UserInfo> infoList=new ArrayList<UserInfo>();
infoList.add(userInfo);
infoList.add(userInfo1);
/***
* 将数据推送到双列集合中
*/
//valueStack.push(infoList);将泛型集合推送到值栈中,没有引用地址
this.List=infoList;
valueStack.getContext().put("infoList",infoList); return "demo1";
} }

UserInfo:

package com.gdbd.bean;

import java.io.Serializable;

/**
* user 实体类
* @author asus
*/
public class UserInfo implements Serializable { private String userName;
private String userPwd; ...省略 Get Set
}

struts.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts> <!-- 是否开启动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<!--更改 Struts.xml的 节点不需要重启-->
<constant name="struts.devMode" value="true"></constant> <!--动态-->
<package name="default" namespace="/" extends="struts-default"> <!--动态方法调度 使用( ! ) -->
<action name="demo" class="com.gdbd.action.CoordinAction">
<result name="add">/error.jsp</result>
</action>
<!--
*_*:
第一个 * 为 类名
第二个 * 为 方法名
-->
<!--万能通配符-->
<action name="*_*" class="com.gdbd.action.{1}" method="{2}">
<result name="{2}">{1}/{2}.jsp</result>
</action> </package> <!--内部方法的调用-->
<package name="demo" namespace="/demo1" extends="struts-default"> <!--
action 内部方法调度
-->
<action name="mo" class="com.gdbd.action.CoordinAction" method="demo1">
<result name="demo2">/demo2.jsp</result>
</action>
<!--
action 内部方法调度 重定向页面
-->
<action name="mo1" class="com.gdbd.action.CoordinAction" method="demo1">
<result name="demo2" type="redirect">/demo2.jsp</result>
</action> </package> <!--调度 action 中的方法,在根据结果集再次跳转到 action 方法 -->
<package name="demo2" namespace="/demo2" extends="struts-default"> <action name="listdemo" class="com.gdbd.action.CoordinAction" method="list">
<result name="list">/demo2.jsp</result>
</action> <action name="mo" class="com.gdbd.action.CoordinAction" method="add">
<result name="add" type="chain">
<!--默认是转发-->
<param name="actionName">listdemo</param>
<param name="namespace">/demo2</param>
</result>
</action> </package> <!--动态结果:重定向页面(转发无效)-->
<package name="demo3" namespace="/demo3" extends="struts-default"> <action name="mo" class="com.gdbd.action.CoordinAction" method="get">
<result name="get" type="redirect">${mess}</result>
</action>
<action name="demo2">
<result>/demo2.jsp</result>
</action>
<action name="error">
<result>/error.jsp</result>
</action> </package> <!--OGNL 测试-->
<package name="demo4" namespace="/demo4" extends="struts-default"> <!--推送到单列集合中-->
<action name="mo" class="com.gdbd.action.OgnlAction" method="demo1">
<result name="demo1">/demo1.jsp</result>
</action>
<!--推送到双列集合中-->
<action name="mo1" class="com.gdbd.action.OgnlAction" method="demo2">
<result name="demo1">/demo1.jsp</result>
</action>
</package> </struts>

add.jsp:

<%--
Created by IntelliJ IDEA.
User: asus
Date: 2018/11/17
Time: 9:33
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>add==========</h1>
</body>
</html>

list.jsp:

<%--
Created by IntelliJ IDEA.
User: asus
Date: 2018/11/17
Time: 9:33
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>list==========</h1>
</body>
</html>

demo1.jsp:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
Created by IntelliJ IDEA.
User: asus
Date: 2018/11/17
Time: 9:33
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<fieldset>
<legend>OGNL:获取的结果(值栈单列集合)</legend>
姓名为:<s:property value="userName"></s:property>
<br/>
密码为:<s:property value="userPwd"></s:property>
</fieldset>
<br/><br/>
<fieldset>
<legend>OGNL:获取的结果(值栈Root 单列集合)</legend>
姓名为:<s:property value="List[0].userName"></s:property>
<br/>
密码为:<s:property value="List[1].userPwd"></s:property>
</fieldset>
<br/><br/>
<fieldset>
<legend>OGNL:获取的结果(值栈双列集合)</legend>
姓名为:<s:property value="#infoList[0].userName"></s:property>
<br/>
密码为:<s:property value="#infoList[1].userPwd"></s:property>
</fieldset>
<br/><br/>
<fieldset>
<legend>OGNL:获取的结果(值栈双列集合,便利读取)</legend>
<s:iterator value="infoList" id="info">
<s:property value="#info.userName"/>
</s:iterator>
</fieldset>
<br/><br/>
<s:debug/>
</body>
</html>

demo2.jsp:

<%--
Created by IntelliJ IDEA.
User: asus
Date: 2018/11/17
Time: 9:33
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>

error.jsp:

<%--
Created by IntelliJ IDEA.
User: asus
Date: 2018/11/17
Time: 9:33
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>

index.jsp:

<%--
Created by IntelliJ IDEA.
User: asus
Date: 2018/11/17
Time: 10:34
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<fieldset>
<legend>动态方法调度</legend>
<a href="/demo!add">动态方法调度</a>
</fieldset>
<br/><br/>
<fieldset>
<legend>万能通配符</legend>
<a href="/CoordinAction_list">万能通配符</a>
&nbsp;&nbsp;&nbsp;
<a href="/CoordinAction_add">万能通配符</a>
</fieldset>
<br/><br/>
<fieldset>
<legend>内部方法调度返回的信息</legend>
<a href="/demo1/mo">内部方法调度返回的信息:默认是转发</a>
&nbsp;&nbsp;&nbsp;
<a href="/demo1/mo1">内部方法调度返回的信息:使用重定向</a>
</fieldset>
<br/><br/>
<fieldset>
<legend>调度 action 中的方法,在根据结果集再次跳转到 action 方法</legend>
<a href="/demo2/mo">跳转 add 方法 根据结果再次 指向list:转发操作</a>
&nbsp;&nbsp;&nbsp;
<a href="#">###</a>
</fieldset>
<br/><br/>
<fieldset>
<legend>动态结果调度</legend>
<a href="/demo3/mo?message=123">动态结果调度:重定向</a>
&nbsp;&nbsp;&nbsp;
<a href="#">###</a>
</fieldset>
<br/><br/>
<fieldset>
<legend>OGNL</legend>
<a href="/demo4/mo">OGNL:存储到值栈的单列集合</a>
&nbsp;&nbsp;&nbsp;
<a href="/demo4/mo1">OGNL:存储到值栈的单列集合</a>
&nbsp;&nbsp;&nbsp;
</fieldset>
<br/><br/>
</body>
</html>

web.xml:

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app>
<display-name>Archetype Created Web Application</display-name> <!--核心过滤器-->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> </web-app>

分享知识-快乐自己:Struts2(动态方法、动态结果、通配符、方法内部跳转、action跳转、OGNL 的使用及注意事项)的更多相关文章

  1. 分享知识-快乐自己:Mybatis 基础动态语句

    目录: User: package mlq.bean; /** * 用户实体类 */ public class User { private Integer uId; private String u ...

  2. 分享知识-快乐自己:List 集合去重合并 , 多种方法演示

    最近空闲时间去面试 , 被问了一个问题list如何去重合并 , 想了半天只想到了最繁琐的循环方法 , 顿觉丢人. 整理一下资料供大家参考: List<String> a = new Arr ...

  3. Struts2学习四----------动态方法调用

    © 版权声明:本文为博主原创文章,转载请注明出处 Struts2动态方法调用 - 默认:默认执行方法中的execute方法,若指定类中没有该方法,默认返回success <package nam ...

  4. Struts2的多方法动态Action

    原创 一个简单的Action里面的核心方法只有一个execute(); 定义多个核心方法的Action,有如下3种方式: 为Action配置method属性 动态方法调用 使用通配符映射方式 动态方法 ...

  5. Struts2深入之动态调用Action

    使用过Struts2的小伙伴们应该知道当我们的action的方法过多是如果需要通过Struts2框架进行运行,我们就必须在Struts2的配置文件Struts2.xml文件中配置多个action属性标 ...

  6. 10、一个action中处理多个方法的调用第一种方法动态调用

    我们新建一个用户的action package com.weiyuan.test; import com.opensymphony.xwork2.ActionSupport; /** * * 这里不用 ...

  7. 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间

    [源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...

  8. Delphi动态事件深入分析(对象方法在调用的时候会传递一个隐含的Self指针,而该指针的值在EAX中。即左边第一个参数)

    Delphi动态事件深入分析 2009-2-7 作者:不得闲核心提示:本实验证明了在类中方法的调用时候,所有的方法都隐含了一个Self参数,并且该参数作为对象方法的第一个参数传递... 首先做一个空窗 ...

  9. select 下拉菜单Option对象使用add(elements,index)方法动态添加

    原生js 的add函数为下拉菜单增加选项 1.object.add(oElement [, iIndex]) index 可选参数:指定元素放置所在的索引号,整形值.如果没有指定值,将添加到集合的最后 ...

随机推荐

  1. (转)微信小程序开发项目——笑话大全

    此项目是学习完微信小程序后实现的一个demo,采用聚合数据的免费api获取最新的文本笑话和趣图(图片和gif图)   项目地址:https://github.com/zhijieeeeee/wecha ...

  2. 常用快递API及快递在线下单API分享

    1.常用快递API 支持顺丰.EMS.申通.圆通.韵达.汇通.中通.天天.德邦.全峰等主流快递公司. 文档地址:https://www.juhe.cn/docs/api/id/43 1.1常用快递查询 ...

  3. Struts2中Action自己主动接收參数

    Struts2中Action接收參数的方法主要有下面三种: 1.使用Action的属性接收參数:(通过属性驱动式)     a.定义:在Action类中定义属性,创建get和set方法.     b. ...

  4. WebService中获取request对象一例

    @WebService @Service public class WeiXinWebServiceImpl implements IWeiXinWebService { @Resource priv ...

  5. mybatis技术文章

    http://legend2011.blog.51cto.com/3018495/1600478

  6. websocket-client connection( Long-lived )

    参考:https://pypi.python.org/pypi/websocket-client/ import websocket import thread import time def on_ ...

  7. Linux 下wifi 驱动开发(三)—— SDIO接口WiFi驱动浅析

    SDIO-Wifi模块是基于SDIO接口的符合wifi无线网络标准的嵌入式模块,内置无线网络协议IEEE802.11协议栈以及TCP/IP协议栈.可以实现用户主平台数据通过SDIO口到无线网络之间的转 ...

  8. Spring学习四----------Bean的配置之Bean的配置项及作用域

    © 版权声明:本文为博主原创文章,转载请注明出处 Bean的作用域(每个作用域都是在同一个Bean容器中) 1.singleton:单例,指一个Bean容器中只存在一份(默认) 2.prototype ...

  9. grunt使用一步一步讲解

    grunt 是一套前端自动化工具,一个基于nodeJs的命令行工具,一般用于:① 压缩文件② 合并文件③ 简单语法检查 对于其他用法,我还不太清楚,我们这里简单介绍下grunt的压缩.合并文件,初学, ...

  10. java利用爬虫技术抓取(省、市(区号\邮编)、县)数据

    近期项目须要用到 城市的地址信息,但从网上下载的xml数据没有几个是最新的地址信息.....数据太老,导致有些地区不全.所以才想到天气预报官网特定有最新最全的数据.贴出代码,希望能给有相同困惑的朋友. ...