【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 会为每个请求创建一个新的值栈, ...
随机推荐
- 用bochs调试自己写的系统引导代码
1 安装和配置bochs 首先从bochs.sourceforge.net里面把BOCHS给download下来,鉴于Windows的普及,仅仅谈BOCHS在win下的使用方法,其实在其它的OS中方法 ...
- Eclipse导入GitLab中指定分支的项目
一.如果主分支丢失,是否可以恢复其他分支? 答案是可以的,下面我们就拿恢复分支publish-2018-6-5来说明问题,最终实现把分支publish-2018-6-5还原成项目放到Eclipse中 ...
- (转)Debug Assertion Failed! Expression: _pFirstBlock == pHead
最近在VS上开发C++程序时遇到了这个错误: Debug Assertion Failed! Expression:_pFirstBlock == pHead 如图: 点击Abort之后,查看调用 ...
- VC++ MFC应用程序项目文件
<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Bu ...
- [Functional Programming] Arrow contramap vs map and promap
In previous post, Arrow Functor with contramap, we have seen how to opreating on params before we in ...
- 使用visual studio code调试php代码
这回使用visual studio code折腾php代码的调试,又是一顿折腾,无论如何都进不了断点.好在就要放弃使用visual studio code工具的时候,折腾好了,汗~ 这里把步骤记录下来 ...
- Jquery——几个注意的小知识
event.stopPropagation() 停止事件冒泡 event.preventDefault()//组织默认行为(例如错误的时候,阻止按钮提交) event.type获取事件类型 event ...
- 国外某牛人的JsonModelBinder 实现 MVC 3.0
public class JsonModelBinder : DefaultModelBinder { public override object BindModel(ControllerConte ...
- mahout做推荐时uid,pid为string类型
很幸运找到这篇文件,解了燃眉之急. http://blog.csdn.net/pan12jian/article/details/38703569 mahout做推荐的输入只能是long类型,但在某些 ...
- flume-ng-elasticsearch 索引时间命名问题(时区和时间格式)
目前版本还不支持,只把索引名称的加载项传递过去了