栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ognl表达式系列1--OgnlContext

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ognl表达式系列1--OgnlContext

OGNL(Object-Graph Navigation Languaged)对象图导航语言,它是一种功能强大的第三方表达式语言。java中其他表达式语言还有EL,JSTL等。

目的:为了解struts2,弄懂ValueStack(据说struts2用的不多了,但一个mvc框架,学习一下还是可以的吧),因为struts2在项目中集成了OGNL,struts2默认的表达式语言就是OGNL。

OGNL的使用要素 就是 表达式 || 根对象 || Context对象

这里 就 先 探秘 OgnlContext类。

1)OgnlContext继承自Map接口(但是OgnlContext 内 _values 属性才是核心,也要注意_root这个属性。)

package ognl;
import ognl.enhance.LocalReference;
import java.util.*;
public class OgnlContext extends Object implements Map{}

与 _root 有关的一些代码如下

private Object _root;
private Object _currentObject;
public void setRoot(Object value)
    {
        _root = value;
        _accessorStack.clear();
        _typeStack.clear();
        _currentObject = value;
        if (_currentObject != null)
        {
            setCurrentType(_currentObject.getClass());
        }
    }
public Object getRoot(){ return _root; }

public void setCurrentType(Class type){ _typeStack.add(type); }

public void setCurrentObject(Object value){ _currentObject = value; }

public Object getCurrentObject(){ return _currentObject; }
    

与 _values 有关的一些代码如下

//定义 _values 属性

private Map _values = new HashMap(23);

//构造函数初始化 _values 
public OgnlContext(Map values)
    {
        super();
        this._values = values;
    }
//设置 _values 的值
public void setValues(Map value)
    {
        for(Iterator it = value.keySet().iterator(); it.hasNext();) {
            Object k = it.next();

            _values.put(k, value.get(k));
        }
    }
//获取 _values 的值
public Map getValues() { return _values;  }

实现Map接口的方法如下(全部和 _values 有关)

  
    public int size(){ return _values.size(); }
    
    public boolean isEmpty(){ return _values.isEmpty(); }
    
    public boolean containsKey(Object key){ return _values.containsKey(key); }
    
    public boolean containsValue(Object value){ return _values.containsValue(value); }
    
    public void clear(){ ...;  _values.clear(); setRoot(null);  ...; }
    
    public Set keySet(){ return _values.keySet(); }
    
    public Collection values(){ return _values.values(); }
    
    public Set entrySet(){ return _values.entrySet(); }
    
    public boolean equals(Object o){ return _values.equals(o); }
    
    public int hashCode(){ return _values.hashCode(); }

    public Object get(Object key)
    {
        Object result;
		//RESERVED_KEYS的11个保留的key,context,this,root等
		//private static Map RESERVED_KEYS = new HashMap(11);
		//RESERVED_KEYS.put(CONTEXT_CONTEXT_KEY, null);
        //RESERVED_KEYS.put(ROOT_CONTEXT_KEY, null);
        //RESERVED_KEYS.put(THIS_CONTEXT_KEY, null);
        if (RESERVED_KEYS.containsKey(key)) {
        	//"this" 由setRoot方法可知,_currentObject 和 _root的值 一般相等
            if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {
                result = getCurrentObject();
            } else {
            	//"root"
                if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {
                    result = getRoot();
                } else {
                	//"context",返回当前OgnlContext对象
                    if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {
                        result = this;
                    } 
                    //代码省略
        } else {
        除了上面的那些情况,就从_values中取值
            result = _values.get(key);
        }
        return result;
    }

    public Object put(Object key, Object value)
    {
        Object result;
        
        if (RESERVED_KEYS.containsKey(key)) {
            if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {
                result = getCurrentObject();
                setCurrentObject(value);
            } else {
                if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {
                    result = getRoot();
                    setRoot(value);
                } else {
                	//context就是当前OgnlContext对象,不允许修改context的指向
                    if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {
                        throw new IllegalArgumentException("can't change " + OgnlContext.CONTEXT_CONTEXT_KEY
                                + " in context");
                    }
                    //代码省略
          else {
          //key不在预留的11个字符串中,那就把key-value对 put进 _value中
            result = _values.put(key, value);
        }
        
        return result;
    }

    public Object remove(Object key)
    {
        Object result;

        if (RESERVED_KEYS.containsKey(key)) {
            if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {
                result = getCurrentObject();
                setCurrentObject(null);
            } else {
                if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {
                    result = getRoot();
                    setRoot(null);
                } else {
                		//context就是当前OgnlContext对象,不允许修改context的指向,当然就不允许为空
                    if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {
                        throw new IllegalArgumentException("can't remove " + OgnlContext.CONTEXT_CONTEXT_KEY
                                + " from context");
                    } 
                    //代码省略
        else {
            result = _values.remove(key);
        }
        return result;
    }

    public void putAll(Map t)
    {
        for(Iterator it = t.keySet().iterator(); it.hasNext();) {
            Object k = it.next();

            put(k, t.get(k));
        }
    }

看完之后,我们发现,其实 OgnlContext也就那样,它基本不依赖其他jar包,虽然实现了Map接口,但大多数数据(除了11个预定义的key,“this”,“root”,"context"等)都存在它的属性 _values 中。_values它就是一个HashMap。。。绕过来绕过去的感觉。。。有种避重就轻的感觉,那这个 OgnlContext 它 到底做了啥?

通过get方法,输入"context",可获得OgnlContext对象本身。

然后这个_root 作用未知。

数据呢,其实都存在了 HashMap中,也就是 _values 中。


OgnlContext 完整代码如下:

evaluations:评价,评估
trace:		跟踪,追溯
resolver:	解析
prefix:		前缀
reserved:	寡言收敛的,预留,保留,保守,储备

OgnlContext 类的代码可自行百度。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/782187.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号