el ognl 的区别.

EL
  1.语法结构 
    ${expression} 
  2.[]与.运算符 
    EL 提供.和[]两种运算符来存取数据。 
    当要存取的属性名称中包含一些特殊字符,如.或?等并非字母或数字的符号,就一定要使用 []。例如: 
        ${user.My-Name}应当改为${user["My-Name"] } 
    如果要动态取值时,就可以用[]来做,而.无法做到动态取值。例如: 
        ${sessionScope.user[data]}中data 是一个变量 
  3.变量 
    EL存取变量数据的方法很简单,例如:
      ${username}。它的意思是取出某一范围中名称为username的变量。
因为我们并没有指定哪一个范围的username,所以它会依序从Page、Request、Session、Application范围查找
假如途中找到username,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传null。 属性范围在EL中的名称 Page   PageScope Request RequestScope Session SessionScope Application ApplicationScope

  cookie     例:要取得cookie中有一个设定名称为userCountry的值,可以使用${cookie.userCountry}来取得它。
    header和headerValues
  header 储存用户浏览器和服务端用来沟通的数据     例:要取得用户浏览器的版本,可以使用${header["User-Agent"]}     另外在鲜少机会下,有可能同一标头名称拥有不同的值,此时必须改为使用headerValues 来取得这些值。

  initParam   initParam取得设定web站点的环境参数(Context)
    例:一般的方法 String userid = (String)application.getInitParameter("userid");
      可以使用 ${initParam.userid}来取得名称为userid
 
  pageContext    pageContext取得其他有关用户要求或页面的详细信息。     ${pageContext.request.queryString}         取得请求的参数字符串     ${pageContext.request.requestURL}         取得请求的URL,但不包括请求之参数字符串     ${pageContext.request.contextPath}         服务的web application 的名称     ${pageContext.request.method}           取得HTTP 的方法(GET、POST)     ${pageContext.request.protocol}         取得使用的协议(HTTP/1.1、HTTP/1.0)     ${pageContext.request.remoteUser}         取得用户名称     ${pageContext.request.remoteAddr }         取得用户的IP 地址     ${pageContext.session.new}             判断session 是否为新的     ${pageContext.session.id}               取得session 的ID     ${pageContext.servletContext.serverInfo}   取得主机端的服务信息 

  补充:
    1.EL表达式用${}表示,可用在所有的HTML和JSP标签中 作用是代替JSP页面中复杂的JAVA代码.
        2.EL表达式可操作常量, 变量和隐式对象.
      最常用的 隐式对象有${param}和${paramValues}.         ${param}表示返回请求参数中单个字符串的值.         ${paramValues}表示返回请求参数的一组值.

      pageScope表示页面范围的变量.
      requestScope表示请求对象的变量.       sessionScope表示会话范围内的变量.
      applicationScope表示应用范围的变量.

        3.<%@ page isELIgnored="true"%> 表示是否禁用EL语言,TRUE表示禁止.FALSE表示不禁止.
      JSP2.0中默认的启用EL语言.
        4.EL语言可显示
      1.算术运算符有五个:+、-、*或$、/或div、%或mod       2.关系运算符有六个:== 或 eq、!= 或 ne、< 或lt、> 或 gt、<= 或 le、>= 或 ge       3.逻辑运算符有三个:&& 或 and、|| 或 or、! 或 not
       4.其它运算符有三个:Empty运算符、条件运算符、()运算符
          例:${empty param.name}、${A?B:C}、${A*(B+C)} 
      
      逻辑表达式如${true and false}结果是false   
      关系表达式如${5>6} 结果是false    
      算术表达式如 ${5+5} 结果是10

        5.EL中的变量搜索范围是:page request session application  
      点运算符(.)和"[]"都是表示获取变量的值.
      区别是[]可以显示非词类的变量

OGNL
OGNL是一个对象,属性的查询语言。
为了解决数据从View层传递到Controller层时的不匹配性,Struts2采纳了XWork的OGNL方案。并且在OGNL的基础上,构建了OGNLValueStack的机制,从而比较完美的解决了数据流转中的不匹配性。

OGNL(Object Graph Navigation Language),是一种表达式语言。使用这种表达式语言,你可以通过某种表达式语法,存取Java对象树中的任意属性、调用Java对象树的方法、同时能够自动实现必要的类型转化。如果我们把表达式看做是一个带有语义的字符串,那么OGNL无疑成为了这个语义字符串与Java对象之间沟通的桥梁。
public class OGNLTestCase extends TestCase {   
        
    @Test  
    public void testGetValue() throws Exception {   
           
        // Create root object   
        User user = new User();   
        user.setId(1);   
        user.setName("downpour");   
  
        // Create context   
        Map context = new HashMap();   
        context.put("introduction","My name is ");   
           
        // Test to directly get value from root object, with no context   
        Object name = Ognl.getValue(Ognl.parseExpression("name"), user);   
        assertEquals("downpour",name);   
           
        // Test to get value(parameter) from context   
        Object contextValue = Ognl.getValue(Ognl.parseExpression("#introduction"), context, user);   
        assertEquals("My name is ", contextValue);   
           
        // Test to get value and parameter from root object and context   
        Object hello = Ognl.getValue(Ognl.parseExpression("#introduction + name"), context, user);   
        assertEquals("My name is downpour",hello);   
                       
    }   
  
    @Test  
    public void testSetValue() throws Exception {   
           
        // Create root object   
        User user = new User();   
        user.setId(1);   
        user.setName("downpour");   
           
        // Set value according to the expression   
        Ognl.setValue("department.name", user, "dev");   
        assertEquals("dev", user.getDepartment().getName());      
    }   

}  

 

1. 表达式(Expression) 

表达式是整个OGNL的核心,所有的OGNL操作都是针对表达式的解析后进行的。表达式会规定此次OGNL操作到底要干什么
我们可以看到,在上面的测试中,name、department.name等都是表达式,表示取name或者department中的name的值。OGNL支持很多类型的表达式,之后我们会看到更多。
2. 根对象(Root Object)

根对象可以理解为OGNL的操作对象。在表达式规定了“干什么”以后,你还需要指定到底“对谁干”
在上面的测试代码中,user就是根对象。这就意味着,我们需要对user这个对象去取name这个属性的值(对user这个对象去设置其中的department中的name属性值)。
3. 上下文环境(Context)
有了表达式和根对象,我们实际上已经可以使用OGNL的基本功能。例如,根据表达式对根对象进行取值或者设值工作。
不过实际上,在OGNL的内部,所有的操作都会在一个特定的环境中运行,这个环境就是OGNL的上下文环境(Context)。说得再明白一些,就是这个上下文环境(Context),将规定OGNL的操作“在哪里干”

OGNL的上下文环境是一个Map结构,称之为OgnlContext。上面我们提到的根对象(Root Object),事实上也会被加入到上下文环境中去,并且这将作为一个特殊的变量进行处理,具体就表现为针对根对象(Root Object)的存取操作的表达式是不需要增加#符号进行区分的。
OgnlContext不仅提供了OGNL的运行环境。在这其中,我们还能设置一些自定义的parameter到Context中,以便我们在进行OGNL操作的时候能够方便的使用这些parameter。不过正如我们上面反复强调的,我们在访问这些parameter时,需要使用#作为前缀才能进行。
OGNL表达式

OGNL支持各种纷繁复杂的表达式。但是最最基本的表达式的原型,是将对象的引用值用点串联起来,从左到右,每一次表达式计算返回的结果成为当前对象,后面部分接着在当前对象上进行计算,一直到全部表达式计算完成,返回最后得到的对象。OGNL则针对这条基本原则进行不断的扩充,从而使之支持对象树、数组、容器的访问,甚至是类似SQL中的投影选择等操作。
接下来我们就来看看一些常用的OGNL表达式:

1. 基本对象树的访问
对象树的访问就是通过使用点号将对象的引用串联起来进行。
例如:name,department.name,user.department.factory.manager.name
2. 对容器变量的访问
对容器变量的访问,通过#符号加上表达式进行。
例如:#name,#department.name,#user.department.factory.manager.name
3. 使用操作符号
OGNL表达式中能使用的操作符基本跟Java里的操作符一样,除了能使用 +, -, *, /, ++, --, ==, !=, = 等操作符之外,还能使用 mod, in, not in等。

4. 容器、数组、对象

OGNL支持对数组和ArrayList等容器的顺序访问:

例如:group.users[0]
同时,OGNL支持对Map的按键值查找:
例如:#session['mySessionPropKey']
不仅如此,OGNL还支持容器的构造的表达式:
例如:{"green", "red", "blue"}构造一个List,#{"key1" : "value1", "key2" : "value2", "key3" : "value3"}构造一个Map

你也可以通过任意类对象的构造函数进行对象新建:
例如:new java.net.URL("http://localhost/")

5. 对静态方法或变量的访问
要引用类的静态方法和字段,他们的表达方式是一样的@class@member或者@class@method(args):
例如:@com.javaeye.core.Resource@ENABLE,@com.javaeye.core.Resource@getAllResources
6. 方法调用

直接通过类似Java的方法调用方式进行,你甚至可以传递参数:
例如:user.getName(),group.users.size(),group.containsUser(#requestUser)

7. 投影和选择
OGNL支持类似数据库中的投影(projection) 和选择(selection)。

投影就是选出集合中每个元素的相同属性组成新的集合,类似于关系数据库的字段操作。投影操作语法为 collection.{XXX},其中XXX 是这个集合中每个元素的公共属性。

例如:group.userList.{username}将获得某个group中的所有user的name的列表。
选择就是过滤满足selection 条件的集合元素,类似于关系数据库的纪录操作。选择操作的语法为:collection.{X YYY},其中X 是一个选择操作符,后面则是选择用的逻辑表达式。而选择操作符有三种:
? 选择满足条件的所有元素
^ 选择满足条件的第一个元素
$ 选择满足条件的最后一个元素

例如:group.userList.{? #this.name != null}将获得某个group中user的name不为空的user的列表。
上述的所有的表达式,只是对OGNL所有表达式的大概的一个概括,除此之外,OGNL还有更多的表达式,例如lamba表达式等等。最具体的表达式的文档,大家可以参考OGNL自带的文档:
http://www.ognl.org/2.6.9/Documentation/html/LanguageGuide/apa.html



顺便看一下 ActionContext..
  

ActionContext 里面有一个 Map<String, Object> context;
然后是

//public static final String DEV_MODE = "__devMode";

public static final String ACTION_NAME = "com.opensymphony.xwork2.ActionContext.name";

public static final String VALUE_STACK = ValueStack.VALUE_STACK;

public static final String SESSION = "com.opensymphony.xwork2.ActionContext.session";

public static final String APPLICATION = "com.opensymphony.xwork2.ActionContext.application";

public static final String PARAMETERS = "com.opensymphony.xwork2.ActionContext.parameters";

public static final String LOCALE = "com.opensymphony.xwork2.ActionContext.locale";

public static final String TYPE_CONVERTER = "com.opensymphony.xwork2.ActionContext.typeConverter";

public static final String ACTION_INVOCATION = "com.opensymphony.xwork2.ActionContext.actionInvocation";

public static final String CONVERSION_ERRORS = "com.opensymphony.xwork2.ActionContext.conversionErrors";

public static final String CONTAINER = "com.opensymphony.xwork2.ActionContext.container";

  Action的实例,总是放到value stack中。
  因为Action放在stack中,而stack是root(根对象),所以对Action中的属性的访问就可以省略#标记。
  但是,要访问ActionContext中其它对象的属性,就必须要带上#标记,以便让OGNL知道,不是从根对象,而是从其它对象中去寻找。

ActionContext  一次Action调用都会创建一个ActionContext  调用:ActionContext context = ActionContext.getContext()  
ValueStack 由OGNL框架实现  可以把它简单的看作一个List  
Stack Object:放入stack中的对象,一般是action。
Stack Context(map):stack上下文,它包含一些列对象,包括request/session/attr/application map等。  
EL:存取对象的任意属性,调用对象的方法,遍历整个对象结构图

ActionContext是Action上下文 可以得到request session application ValueStack是值栈 存放表单中的值
Stack Context 栈上下文 也是用来存值的  
=======================================================================================
你可以通过在页面中添加<s:debug/>标签察看ValueStack 和Stack Context中有哪些具体的内容。
ValueStack里面的东西先入后出,很多没有id的元素使用完之后就退栈了。
StackContext提供了一些命名对象,这些命名对象与根对象无关,访问这些对象需要使用#前缀指名。
  比如这里面存在:parameters对象,request对象, session对象,application对象等等。

 

OGNL     在jsp中 %{}

EL    在jsp中 ${}

 

 

posted @ 2012-12-31 12:09  Onakaumi  阅读(479)  评论(0编辑  收藏  举报