浅析=======Struts2之==========valueStack
今天刚学习了struts2的valueStack,在这里把自己学到的做个分享,说道valueStack就不得不提OGNL表达式===
struts2工作流程

1.OGNL(Object Graph Navigation Language)对象导航图语言
Struts2框架使用OGNL作为默认的表达式语言,OGNL(Object Graph Navigation Language),是一种表达式语言,目的是为了在不能写Java代码的地方执行java代码;主要作用是用来存数据和取数据的。
2 valueStack
valueStack是struts2的值栈空间,是struts2存储数据的空间
Strut2的Action类通过属性可以获得所有请求相关的值,要在Action类中声明与参数同名的属性或者以类名小写加属性名如:user.name,就可以获得这些参数值,在Struts2调用Action类的Action方法(默认是execute方法)之前,就会为相应的Action属性赋值。这项功能Struts2要依赖于ValueStack对象来实现,每个Action类的对象实例会拥有一个ValueStack对象,这个对象贯穿整个Action的生命周期,
当Struts2接收到一个请求后,会先建立Action类的对象实例,但并不会立即调用Action方法,而是先将Action类的相应属性放到ValueStack实现类ONGLValueStack对象root对象的顶层节点。只是所有的属性值都是默认的值,如String类型的属性值为null,int类型的属性值为0等。在处理完上述工作后,Struts 2就会调用拦截器链中的拦截器,这些拦截器会根据用户请求参数值去更新ValueStack对象顶层节点的相应属性的值,最后会传到Action对象,并将ValueStack对象中的属性值,赋给Action类的相应属性。当调用完所有的拦截器后,才会调用Action类的Action方法。ValueStack会在请求开始时被创建,请求结束时消亡。
3.valueStack底层相关的数据结构

CompoundRoot是继承了Arraylist的集合,里面存放Action的实例、代理对象、自定义对象(Student)等数据
5 代码展示valueStack
需求:通过页面跳转到指定的Action的方法中,在方法中通过
创建student实体类
package com.xsh.pojo;
public class Student {
private String name;
public Student(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
struts.xml配置文件
<?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>
<constant name="struts.devMode" value="true"/>
<package name="default" namespace="/user" extends="struts-default">
<action name="login" class="com.xsh.test.LoginAction" method="execute">
<result>/success.jsp</result>
</action>
</package>
</struts>
Action类
package com.xsh.test;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
import com.xsh.pojo.Student;
public class LoginAction extends ActionSupport {
public String execute(){
System.out.println("进入方法=====");
Map<String, Object> session = ActionContext.getContext().getSession();
session.put("sessionName", "sessionName");
Map<String, Object> request = (Map<String, Object>) ActionContext.getContext().get("request");
request.put("requestName", "requestName");
Map<String, Object> application = ActionContext.getContext().getApplication();
application.put("applicationName", "applicationName");
ValueStack valueStack = (ValueStack) request.get("struts.valueStack");//通过request对象获得valueStack对象
System.out.println("valueStack的值======"); valueStack.getRoot().add(new Student("小白白"));//向valueStack的root属性中添加自定义值
System.out.println(valueStack); return SUCCESS; } }
strut2的底层getroot()是接口ValueStack 定义的方法,返回CompoundRoot继承了Arraylist的集合
/**
* Get the CompoundRoot which holds the objects pushed onto the stack
*
* @return the root
*/
public abstract CompoundRoot getRoot();
/**
* A Stack that is implemented using a List.
*
* @author plightbo
* @version $Revision$
*/
public class CompoundRoot extends ArrayList { public CompoundRoot() {
} public CompoundRoot(List list) {
super(list);
} public CompoundRoot cutStack(int index) {
return new CompoundRoot(subList(index, size()));
} public Object peek() {
return get(0);
} public Object pop() {
return remove(0);
} public void push(Object o) {
add(0, o);
}
}
登录实现跳转页面login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
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 'login.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>
<h1><a href="user/login">Check ValueStack</a></h1>
</body>
</html>
跳转成功页面success.jsp
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 'success.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">
-->
<%@ taglib prefix="s" uri="/struts-tags" %>
</head> <body>
<h1><s:debug/></h1>
</body>
</html>
点击查看ValueStack,标题进入旋转状态(前提在代码内打好断点),查看断电是的valueStack的状态,如图


在debug模式中,f6,继续查看变化,通过getRoot()方法获得的集合对象的add方法添加的Student方法已经添加到

5.运输处结果

打印ValueStack对象的hash码是OnglValueStack,查看ObglValueStack类
可知:
a.OgnlValueStack实现了ValueStack的接口
b.属性root是 CompoundRoot类型,CompoundRoot继承了Arraylist的集合
c.context是一个Map<String, Object>类型的集合
d.通过Context的get(key)方法获得的Session、request、Application对象还是还是一个Map<String, Object>类型的集合
/**
* Ognl implementation of a value stack that allows for dynamic Ognl expressions to be evaluated against it. When evaluating an expression,
* the stack will be searched down the stack, from the latest objects pushed in to the earliest, looking for a bean with a getter or setter
* for the given property or a method of the given name (depending on the expression being evaluated).
*
* @author Patrick Lightbody
* @author tm_jee
* @version $Date$ $Id$
*/
public class OgnlValueStack implements Serializable, ValueStack, ClearableValueStack, MemberAccessValueStack { public static final String THROW_EXCEPTION_ON_FAILURE = OgnlValueStack.class.getName() + ".throwExceptionOnFailure"; private static final long serialVersionUID = 370737852934925530L; private static final String MAP_IDENTIFIER_KEY = "com.opensymphony.xwork2.util.OgnlValueStack.MAP_IDENTIFIER_KEY";
private static final Logger LOG = LoggerFactory.getLogger(OgnlValueStack.class); CompoundRoot root;
transient Map<String, Object> context;
Class defaultType;
Map<Object, Object> overrides;
transient OgnlUtil ognlUtil;
transient SecurityMemberAccess securityMemberAccess; private boolean devMode;
浅析=======Struts2之==========valueStack的更多相关文章
- Struts2:ValueStack
一.ValueStack 1 .ValueStack是一个接口,在struts2中使用OGNL(Object-Graph Navigation Language)表达式实际上是使用 ...
- Struts2中ValueStack结构和总结
[ValueStack和ActionContext的关系] 首先,从结构上来看ValueStack是ActionContext的一个组成部分,是对ActionContext功能的扩展.ActionCo ...
- 浅析Struts2中的OGNL和ValueStack
要了解Struts2与OGNL表达式的关系,我们必须先搞清楚以下三个概念: 1. ActionContext它是Action运行的上下文环境,Action的多项设置都存放在次,我们每一次Action ...
- struts2重点——ValueStack和OGNL
一.值栈(ValueStack) 1.实现类:OGNLValueStack 2.对象栈:CompoundRoot(针对的是类级别的) (1)继承自 ArrayList —— 先进后出 (2)提供了栈的 ...
- Struts2之ValueStack、ActionContext
今天在看Action获取Resquest.Response时,发现了一个词:值栈.于是今天一天都在看,了解了值栈不仅能知道Action怎么获取request.response等这些,还会了解OGNL语 ...
- struts2 OGNL ValueStack概念理解 # % $ 的区别
http://blog.csdn.net/tjujacob/article/details/8117659 —————————————————————————————————————————————— ...
- 深度解析Struts2中ValueStack
1.什么是ValueStack 对于每一个action的调用,Struts在执行相应的动作方法之前会先创建一个名为ValueStack的对象.Value Stack用来保存该动作对象或者对象.由于最终 ...
- struts2中valueStack,stackContext以及actionContext的关系
一,首先给出三者的定义 1.valueStack: 里面存放的是Action类中通过set方法设置的属性值(表单传过来的值等),由OGNL框架实现; 2.stackContext: 也是用来存值的,s ...
- Struts2中 ValueStack、ActionContext、ServletContext、request、session等 表格解析
变量 从ActionContext中获得 生命周期 用Ongl来读取值 使用ServletConfigInterceptor来注入 ActionContext类 静态方法ActionContext. ...
随机推荐
- 第十八篇、OC_使用OAStackView FDStackView (第三方框架)可以使用在ios 7及以上的版本
UILabel *view1 = [[UILabel alloc]init]; view1.text = @"Label1"; view1.backgroundColor = [U ...
- Linux目录结构示意详解图
- 部署Sharding分片
这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在sharding 的各个节点上,使用者通过简单的配置就可以很方便地构建一个分布式MongoDB 集群. MongoDB 的数据分块称为 ch ...
- Java高级特性之泛型
首先我们先提出两个问题: 什么是泛型? 为什么要使用泛型?我们先来看看第一个问题什么是泛型.如果你对Java三大特性中的多态性理解的比较透彻的话,泛型就比较好理解了.多态性表示一个对象具备多种状态.比 ...
- MIPS 跳转指令BAL vs JAL
今天调试程序,发现在windows和Linux下,diab编译的结果不一样,一个能跑一个不能跑.最后定位到了函数跳转上. 程序代码里的函数跳转写的是BAL,在windows下编译结果正常,在Linux ...
- Javascript/js的相等和不等运算符(= 、== 、===)
"=="和"==="运算符用于比较两个值是否相等,当然它们对相等的定义不尽相同.两个运算符允许任意类型的操作数,如果操作数相等则返回tru,否则返回false. ...
- 数据流程redux学习(一)
思考题: react+redux开发这么一个原型,要怎么开发? 整个redux流程的逻辑非常清晰,数据流是单向循环的,就像一个生产的流水线: store(存放状态) -> Container(显 ...
- 分布式缓存技术memcached学习系列(四)—— 一致性hash算法原理
分布式一致性hash算法简介 当你看到"分布式一致性hash算法"这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法原理之前, ...
- iterator的实现原理
1.iterator遍历linkedlist集合 Iterator li = list.iterator(); while(li.hasNext()){ System.out.println(li.n ...
- Android仿微信朋友圈,全文收起功能,附源码
在众多的社交类软件中,朋友圈是必不可少的,可以与好友.同学等分享自己的日常和有意思的事情,在开发社交类App时,朋友圈发表的内容你不可能让他全部显示,全部显示的话用户体验度会非常不好,这时就要用到全文 ...