【Struts2】剖析Struts2中的反射技术 ValueStack(值栈)
1,Struts2框架主要组件的处理流程
在说ValueStack之前,笔者先说一说Struts2中常用的组件,struts2中常用组件有strutsPrepareAndExecuteExceptionn,以及一般执行流程:
- 请求来进入 Filter 控制器
- Filter 控制器创建 ValueStack 对象并初始化
- Filter 控制器根据 struts.xml 调用 defaultStack 拦截器栈
- Filter 控制器根据 struts.xml 调用 Action 处理
- Filter 控制器会根据 Action 返回值 +struts.xml 调用 Result 处理
- Filter 控制器销毁 ValueStack 对象信息
- Filter 控制器将 Result 生成的响应信息输出
想必搭建过Struts2框架的读者都知道上面的过程的类几乎都是需要我们在搭建的时候就进行配置。但是ValueStack对象的配置我们并没有显示指定出来,为了研究struts2中反射,我们打开struts-default.xml文件,找到里面的params拦截器(这是struts2框架中所有默认执行拦截器的一种,主要完成对参数的赋值和取值功能),找到它关联的类(ParametersInterceptor)。打开ParametersInterceptor的原码后我们可以在里面看到ValueStack。ValueStack其实是一个接口,其实现子类只有一个OgnlValueStack类。再继续剖析OgnlValueStack类,我们可以看出这个类其实是对OGNL工具包的包装。OGNL是一个封装了反射操作的工具包,因此Struts2底层参数赋值的反射操作是通过使用OGNL这个工具包来完成的。
Struts2中的ValueStack不仅仅用于参数方面,它是用于存储request,session,application,action,parameters等请求相关的数据对象。
下面通过一张图片了解一下ValueStack看一看:

通过这张图片,我们可以非常清楚的了解到valueStack是基于OGNL工具包的,并且valueStack存储数据的形式分为两种root好context。root是ArrayList栈结构,并且Action对象是最后压入栈的,所以Action对象永远在栈的最顶部。另一种存储数据的结构是Context,它和root不同,context是一种map结构。
2,OGNL工具的使用
OGNL是Object Graphics Navigation Language 的简写,是一种对象图导航语言。
上面介绍了ValueStack是基于OGNL工具的,如果说我们也想使用OGNL做一些封装,那么首先应该导入ognl.jar包和javassist-GA.jar包。
Ognl.getValue("OGNL 表达式 ",context,root)
Ognl.getValue("OGNL 表达式",context);
Ognl.getValue("OGNL 表达式",root);
Ognl.setValue("OGNL 表达式 ",context,root,value)
Ognl.setValue("OGNL 表达式",context,value);
Ognl.setValue("OGNL 表达式",root,value);
在有context和root的语句中,可以使用OGNL表达式加以区分操作的对象,如果以#开头表示在context中操作数据,如果不以#开头表示在root中操作数据。

User.java文件
package cn.ongl.test;
public class User {
private int id;
private String userName;
private String userPassword;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
}
User.java
接下来看一看测试:
@Test
public void testName() throws OgnlException{
User user=new User();
user.setId(1);
user.setUserName("jame");
user.setUserPassword("123456");
Object root=user; Map<String,Object> context=new HashMap<String,Object>();
context.put("userName","brace"); //设置为userName,表示将root中userName属性值设置为lucy
Ognl.setValue("userName",context,root, "lucy");
//从root中获取userName字段的值
String uname= (String)Ognl.getValue("userName",context,root);
System.out.println(uname);//lucy
//从context中获取userName的值
uname=(String)Ognl.getValue("#userName", context, root);
System.out.println(uname);//brace //设置为#userName,表示将context中userName属性值设置steven
Ognl.setValue("userName",context,"steven");
//从root中获取userName属性字段的值
uname=(String)Ognl.getValue("userName", context, root);
System.out.println(uname);//lucy //从context中获取userName字段的值
uname=(String)Ognl.getValue("#userName", context,root);
System.out.println(uname);//steven
}
接下来模拟一下请求参数给struts2中Action对象赋值的过程:
Enumeration<String> parameterNames = request.getParameterNames();
//将所有的参数和值封装到parameter中去
Map<String,String> parameters = new HashMap<String,String>();
String value;
String nextElement;
/*
* 循环遍历,将请求的参数以key-value的形式封装到Map集合
*/
while(parameterNames.hasMoreElements()){
nextElement = parameterNames.nextElement();
value=request.getParameter(nextElement);
parameters.put(nextElement, value);
}
//循环访问请求参数,给Action对象中同名的属性赋值
User root = new User();
Set<String> keys = parameters.keySet();
for(String key:keys){
try {
Ognl.setValue(key, root, parameters.get(key));
} catch (OgnlException e) {
e.printStackTrace();
}
}
//打印root对象值
System.out.println(root.getId()+" "
+root.getUserName()+" "+root.getUserPassword());
在上面的请求中,我们只需要得到request,我们也可以完成一个简单的框架自动赋值映射的功能了。
Ognl.getValue("OGNL 表达式",context);
【Struts2】剖析Struts2中的反射技术 ValueStack(值栈)的更多相关文章
- [ SSH框架 ] Struts2框架学习之三(OGNl和ValueStack值栈学习)
一.OGNL概述 1.1 什么是OGNL OGNL的全称是对象图导航语言( object-graph Navigation Language),它是一种功能强大的开源表达式语言,使用这种表达式语言,可 ...
- Android中Java反射技术的使用示例
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...
- 【转】.Net中通过反射技术的应用----插件程序的开发入门
转自:http://www.cnblogs.com/winloa/archive/2012/03/25/2416355.html .Net中通过反射技术的应用----插件程序的开发入门 再开始之前,先 ...
- 第89节:Java中的反射技术
第89节:Java中的反射技术 反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就可以创建对象,将对象的动作完成,这就是动态的获取指定的类). 配置文件把具体实现的类名称定义到配置文件中 ...
- Struts 中 ActionContext ctx.put()把数据放到ValueStack里之数据传输背后机制:ValueStack(值栈)
1. 数据传输背后机制:ValueStack(值栈) 在这一切的背后,是因为有了ValueStack(值栈)! ValueStack基础:OGNL要了解ValueStack,必须先理解OGNL ...
- Struts2笔记3--获取ServletAPI和OGNL与值栈
获取ServletAPI: 第一种方式: //在request域中放入属性req,暂且认为getContext()获取的是request域空间,但实际不是 ActionContext.getConte ...
- Struts2学习(四)———— ognl表达式、值栈、actionContext之间的关系
一.什么是Ognl? 通过百度百科查询到的解释,其中详细的说明了OGNL的作用. 下面我们就对OGNL这5个作用进行讲解 1.存取对象的任意属性,简单说就是对javabean进行操作(重要) 2.调用 ...
- ValueStack值栈和ActionContext
Struts2在OGNL之上提供的最大附加特性就是支持值栈(ValueStack),在OGNL上下文中只能有一个根对象,Struts2的值栈则允许存在许多虚拟对象. 一:值栈(ValueStack) ...
- valueStack(值栈)
值栈 值栈(ValueStack)就是 OGNL 表达式存取数据的地方.在一个值栈中,封装了一次请求所需要的所有数据. 在使用 Struts2 的项目中,Struts2 会为每个请求创建一个新的值栈, ...
随机推荐
- 如何屏蔽ctrl + v 粘贴事件,鼠标右键粘贴事件
通常在自己的APP里的密码框,验证码框需要屏蔽复制,粘贴,怎么办呢? 有三种方法: 1 hook 此方法是最完全的,但由于hook是全局的,容易影响到其它代码. 2 子类化文本框, 重写OnPaste ...
- Docker: 如何将node.js的项目部署到docker的swarm上面去
前提条件: Docker创建虚机和swarm 如何用Docker建立一个Node.js的开发环境 正文: 将如何用Docker建立一个Node.js的开发环境文中创建的nodehello image发 ...
- [Algorithm] How many times is a sorted array rotated?
Given a sorted array, for example: // [2,5,6,8,11,12,15,18] Then we rotated it 1 time, it becomes: / ...
- windows下用qemu搭建android
1.下载Qemu for windows 版本为qemu-0.9.0-windows 2.下载qemuwith-kqemu-support 安装kqemu的目的就是为了加快qemu的子系统运行速度.在 ...
- 保存登录plsql developer 的用户名和密码
1 保存用户名 tools -> Preferences -> User Interface - Options 勾选 Autosave username . 保存 2 保存密码 tool ...
- java enum 用法
/* * Hibernate, Relational Persistence for Idiomatic Java * * Copyright (c) 2010, Red Hat Inc. or th ...
- STL 笔记(四) 迭代器 iterator
stl 中迭代器能够理解为面向对象版本号的广义指针,提供了对容器中的对象的訪问方法,能够遍历容器全部元素.也能够訪问随意元素.stl 迭代器有下面五种: Input iterators 仅仅读,输 ...
- [UIView setShowsFPS:]: unrecognized selector sent to instance XXX
今天在做sprite Kit game时遇到一个问题. 新建一个项目运行时发现就加了这几句代码无法运行.后来一查原来是storyboard uiview要改一下.改成SKview In your st ...
- 高效率、简洁、CSS代码优化原则
高效率.简洁.CSS代码优化原则 CSS学起来并不难,但在大型项目中,一个团队中不同的人在书写CSS风格上也有不同这样这个项目就变得难以管理,团队上就更加难以沟通,为此总结了一些如何实现高效整洁的CS ...
- 牛客网-《剑指offer》-从尾到头打印链表
题目:http://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035 C++ /** * struct ListNode { * i ...