【Struts2】剖析Struts2中的反射技术 ValueStack(值栈)

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);

时间: 2024-12-14 18:07:44

【Struts2】剖析Struts2中的反射技术 ValueStack(值栈)的相关文章

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

一.OGNL概述 1.1 什么是OGNL OGNL的全称是对象图导航语言( object-graph Navigation Language),它是一种功能强大的开源表达式语言,使用这种表达式语言,可以通过某种表达式语法,存取Java对象的任意属性,调用Java对象的方法,同时能够自动实现必要的类型转换.如果把表达式看作是一个带有语义的字符串,那么OGNL无疑成为了这个语义字符串与Java对象之间沟通的桥梁. 1.2 OGNL的作用 Struts2默认的表达式语言就是OGNL,它具有以下特点:

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

import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * Android中Java反射技术的使用示例 * 在Java中描述字节码文件(xxx.class)的类叫Class * 反射的过程可视为剖析Class的过

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

1.     数据传输背后机制:ValueStack(值栈) 在这一切的背后,是因为有了ValueStack(值栈)! ValueStack基础:OGNL要了解ValueStack,必须先理解OGNL(Object Graphic Navigatino Language)! OGNL是Struts2中使用的一种表达式语言,它可以用于JSP的标签库中,以便能够方便的访问各种对象的属性:它用于界面将参数传递到Action(并进行类型转换)中:它还可以用于struts2的配置文件中!所以,非常有必要理

ValueStack值栈和ActionContext

Struts2在OGNL之上提供的最大附加特性就是支持值栈(ValueStack),在OGNL上下文中只能有一个根对象,Struts2的值栈则允许存在许多虚拟对象. 一:值栈(ValueStack) 我们可以先获得ValueStack接口对象 // 01.获取到ValueStack接口对象 ,在request请求中. HttpServletRequest request = ServletActionContext.getRequest(); ValueStack vs = (ValueStac

向值栈中存放数据与从值栈中读取数据

一.set方法方式 1.使用set方法存数据 public class GetValueStackAction extends ActionSupport{ //使用值栈的get方法往值栈中存数据 public String execute(){ //1获取ActionContext对象 ActionContext ctx = ActionContext.getContext(); //2.获取ValueStack对象 ValueStack vs =ctx.getValueStack(); /*

深入分析JavaWeb 48 -- Struts2中OGNL表达式与ValueStack

一.OGNL表达式 1.OGNL表达式介绍 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts2框架使用OGNL作为默认的表达式语言. OGNL相对其它表达式语言具有下面几大优势: 1.支持对象方法调用,如xxx.doSomeSpecial(): 2.支持类静态的方法调用和值访问,表达式的格式: @[类全名(包括包路径)]@[方法名 | 值名],例如:@[email protected]('foo %s', '

struts2中的值栈对象ValueStack

ValueStack, 即值栈对象. 值栈对象: 是整个struts数据存储的核心,或者叫中转站. 用户每次访问struts的action,都会创建一个Action对象.值栈对象.ActionContext对象:  然后把Action对象放入值栈中: 最后再把值栈对象放入request中,传入jsp页面. (key: struts.valueStack):     开发者只需要通过ActionContext对象就可以访问struts的其他的关键对象. (ActionContext是给开发者用的,

Struts2学习之文件上传/下载&amp;ValueStack(三)

简介 今天是学习Struts2第三天,也算struts2准备前奏告一段落,提升部分只能在后期深入了解,多看源码,多参阅资料.今天所学的知识点文件上传.下载/ValueStack&OGNL/Struts2标签 文件上传/下载 文件上传简介 a). 企业常用文件上传技术 : jspSmartUpload(主要应用 JSP model1 时代) . fileupload (Apache commons项目中一个组件). Servlet3.0 集成文件上传 Part类 b). Struts2 对文件上传

[原创]java WEB学习笔记59:Struts2学习之路---OGNL,值栈,读取对象栈中的对象的属性,读取 Context Map 里的对象的属性,调用字段和方法,数组,list,map

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------