1,Struts2框架主要组件的处理流程

在说ValueStack之前,笔者先说一说Struts2中常用的组件,struts2中常用组件有strutsPrepareAndExecuteExceptionn,以及一般执行流程:

  1. 请求来进入 Filter 控制器
  2. Filter 控制器创建 ValueStack 对象并初始化
  3. Filter 控制器根据 struts.xml 调用 defaultStack 拦截器栈
  4. Filter 控制器根据 struts.xml 调用 Action 处理
  5. Filter 控制器会根据 Action 返回值 +struts.xml 调用 Result 处理
  6. Filter 控制器销毁 ValueStack 对象信息
  7. 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(值栈)的更多相关文章

  1. [ SSH框架 ] Struts2框架学习之三(OGNl和ValueStack值栈学习)

    一.OGNL概述 1.1 什么是OGNL OGNL的全称是对象图导航语言( object-graph Navigation Language),它是一种功能强大的开源表达式语言,使用这种表达式语言,可 ...

  2. Android中Java反射技术的使用示例

    import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...

  3. 【转】.Net中通过反射技术的应用----插件程序的开发入门

    转自:http://www.cnblogs.com/winloa/archive/2012/03/25/2416355.html .Net中通过反射技术的应用----插件程序的开发入门 再开始之前,先 ...

  4. 第89节:Java中的反射技术

    第89节:Java中的反射技术 反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就可以创建对象,将对象的动作完成,这就是动态的获取指定的类). 配置文件把具体实现的类名称定义到配置文件中 ...

  5. Struts 中 ActionContext ctx.put()把数据放到ValueStack里之数据传输背后机制:ValueStack(值栈)

    1.     数据传输背后机制:ValueStack(值栈) 在这一切的背后,是因为有了ValueStack(值栈)! ValueStack基础:OGNL要了解ValueStack,必须先理解OGNL ...

  6. Struts2笔记3--获取ServletAPI和OGNL与值栈

    获取ServletAPI: 第一种方式: //在request域中放入属性req,暂且认为getContext()获取的是request域空间,但实际不是 ActionContext.getConte ...

  7. Struts2学习(四)———— ognl表达式、值栈、actionContext之间的关系

    一.什么是Ognl? 通过百度百科查询到的解释,其中详细的说明了OGNL的作用. 下面我们就对OGNL这5个作用进行讲解 1.存取对象的任意属性,简单说就是对javabean进行操作(重要) 2.调用 ...

  8. ValueStack值栈和ActionContext

    Struts2在OGNL之上提供的最大附加特性就是支持值栈(ValueStack),在OGNL上下文中只能有一个根对象,Struts2的值栈则允许存在许多虚拟对象. 一:值栈(ValueStack) ...

  9. valueStack(值栈)

    值栈 值栈(ValueStack)就是 OGNL 表达式存取数据的地方.在一个值栈中,封装了一次请求所需要的所有数据. 在使用 Struts2 的项目中,Struts2 会为每个请求创建一个新的值栈, ...

随机推荐

  1. error MSB6006: "CL.exe" exited with code -1073741819.

    编译一个c++项目的时候,会报如下的错误,总是无法编译,是怎么回事? error MSB6006: "CL.exe" exited with code -1073741819. 搜 ...

  2. curl_setopt — 设置 cURL 传输选项

    curl_setopt (PHP 4 >= 4.0.2, PHP 5, PHP 7) curl_setopt — 设置 cURL 传输选项 bool curl_setopt ( resource ...

  3. PostBuildEvent

    <PostBuildEvent>CALL "%25VS90COMNTOOLS%25\vsvars32.bat" > NULL sn –Vr $(TargetFil ...

  4. XE6入门(二)项目中的文件

    XE6中项目文件为DPR,查看方法请参考一下以前写过的博文: "Delphi项目构成之项目文件DPR" 项目文件DPR 通过主菜单[Project | View Source],就 ...

  5. 放入MP3的文件夹显示一些没用的标题,艺术家,唱片集怎么办?

    原来的文件大小,类型,修改日期,创建日线都没了,怎么办? 右键点击名称,标题,艺术家那一行,在右键菜单中,去掉没用的,勾选有用的,如下图:

  6. Solidworks如何打开swb文件

    把swb文件拖放到Solidworks里面,会弹出窗口选择一个文件夹   随后会自动生成对应的文件,装配体  

  7. C#.NET常见问题(FAQ)-如何把定义存放类实例的数组

    数组存放的可以是普通的int,double,string类型,也可以是自定义的类的实例   如果数组长度未知,可以用list对象存放   更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: h ...

  8. SpeechLib 应用

    //引用组件:Interop.SpeechLib.dll //导入空间:SpeechLib //引用组件:Interop.SpeechLib.dll//导入空间:SpeechLib //1.SpVoi ...

  9. JQuery 之 在数据加载完成后才自动执行函数

    数据加载完成执行: $(window).load(function(){ ... }); 进入页就执行,不论等数据是否加载完成: $(document).ready(function(){ ... } ...

  10. updateFilter

    $.fn.updateFilter = function(filterType, paramVal) { // filter="DATE|GREATERTHANEQUALS|LESSTHAN ...