您的位置:首页 > 编程语言 > Java开发

struts2标签<s:property value=""/> ognl和el

2016-08-09 17:24 597 查看
1、struts2标签解释
http://zhidao.baidu.com/question/88668316.html?fr=qrl&index=0
2、struts2 的标签中 property是什么意思?怎么用?
http://zhidao.baidu.com/question/310639670.html
 Struts2中的property标签<s:property value="...."/>

是用于取得OgnlContext上下文中的属性值,也称为数据标签

特点是取request/session/application/attr/parameters这五个范围时,需要明确指定范围如:

<s:property value="#request.属性名" />,记住,范围前面带#号,如果取ValueStack中的值时,是不需要带#的,可以直接取,因为Action中存储在ValueStack中的,所以取Action中的属性是不需要带#号的,可以直接取.

注意,在action中设置了该属性的setter/getter方法时,该属性才会取到,否则它不会被拦截器处理,value参数的类型是object,可以理解为这个默认是会解析成ognl表达式的。如果需要输入一个字符串<s:property value="'ddd'">注意,在value里面的ddd字符串外面加了单引号,这样不会将ddd解析成ognl表达式了。 

3、Struts2中<s:iterator value=“”> <s:property value=""/>这个value可以动态指定吗? </s:iterator>
http://zhidao.baidu.com/question/258785975.html
你可以看他们的TLD文件,

<attribute>

<name>value</name>

<required>false</required>

<rtexprvalue>false</rtexprvalue>

</attribute>

其中的 rtexprvalue 属性 表示 在运行时刻动态计算还是取编译进行时的静态值,如果为true,它就取得静态值,即:必须给它显现赋值,这里为false,即可以动态指定他们的值。

<s:iterator value="#request.aaa" var="aa" >

<s:iterator value="#session.bbb" var="bb" >

<s:if test="(${bb.name})!=null">                          ------------------未验证

<s:property value="#aa.password"/>

</s:if><s:else>

<s:property value="#aa.name"/>

<s:property value="#aa.password"/>

</else>

 <TD class="x-grid3-table-cell" align="left" title='<s:property value="user" />'>

         

         <s:if test="user==''">---</s:if>

         <s:else><s:property value="user"/></s:else>

        </TD>

注意:若要设置页面表格列中显示的值,可以在action中进行设置值,如:

  public void setResult(String result)

    {

         if ("".equals(result.trim()))

        {

            this.result = "--";

        }

        else

        {

            this.result = result;

        }

    } 


4、EL表达式和ognl表达式

EL一个完全独立的拥有操作符、语法和保留字的编程语言。

EL存取变量数据的方法很简单,如${user}:意思是取出某一范围中名称为user的变量。

EL表达式的默认的范围查找顺序(自动搜索顺序):Page----->Reques---->Session---->Application

也可以指定范围:

–${pageScope.user}

–${requestScope.user}

–${sessionScope.user}

–${applicationScope.user}

至于el是jsp中已经默认的表达式,所以不需要做什么配置。

关于el不起作用的问题,可以通过:

<%@ page isELIgnored="false" %>

这条语句就是说,忽略el为假,等于启用el。

[b]OGNL[b]是[/b]Struts 2默认的表达式语言。是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。[/b]

相对其它表达式语言具有下面几大优势:

1. 支持对象方法调用,如xxx.doSomeSpecial();

2 .支持类静态的方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 | 值名],例如:@Java.lang.String@format('foo
%s', 'bar')或@tutorial.MyConstant@APP_NAME;

3. 支持赋值操作和表达式串联,如price=100, discount=0.8, calculatePrice(),这个表达式会返回80;

4. 访问OGNL上下文(OGNL context)和ActionContext;

5. 操作集合对象。

OGNL的用法:

OGNL是通常要结合Struts 2的标志一起使用,如<s:property value="xx" />

1.“#”主要有三种用途:

访问OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个ActionContext中有用的属性:

 

 名称作用例子
parameters包含当前HTTP请求参数的Map#parameters.id[0]作用相当于request.getParameter("id")
request包含当前HttpServletRequest的属性(attribute)的Map#request.userName相当于request.getAttribute("userName")
session包含当前HttpSession的属性(attribute)的Map#session.userName相当于session.getAttribute("userName")
application包含当前应用的ServletContext的属性(attribute)的Map#application.userName相当于application.getAttribute("userName")
attr用于按request > session > application顺序访问其属性(attribute)#attr.userName相当于按顺序在以上三个范围(scope)内读取userName属性,直到找到为
另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈)。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。

在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象

|--request 

|--application 

context ------|--OgnlValueStack root变量[action, OgnlUtil, ... ] 

|--session 

|--attr 

|--parameters 

在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。

大家注意: Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:<s:property value="name"/>

2.用于过滤和投影(projecting)集合,如books.{?#this.price<100};

3.构造Map,如#{'foo1':'bar1', 'foo2':'bar2'}

 
5、EL和ONGL的对比使用
 
取Session中的值 

<c:out value="${sessionScope.user.userId}"></c:out><br>   

<c:out value="${user.userLoginName}"></c:out><br>     

<s:property value="#session.user.userId"/><br>   

${session.user.userId}<br>  

${sessionScope.user.userId}<br>     

基本语法 

一、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 

        

二、EL隐含对象 

  1.与范围有关的隐含对象 

  与范围有关的EL 隐含对象包含以下四个:pageScope、requestScope、sessionScope 和applicationScope; 

  它们基本上就和JSP的pageContext、request、session和application一样; 

  在EL中,这四个隐含对象只能用来取得范围属性值,即getAttribute(String name),却不能取得其他相关信息。 

  

  例如:我们要取得session中储存一个属性username的值,可以利用下列方法: 

    session.getAttribute("username") 取得username的值, 

  在EL中则使用下列方法 

    ${sessionScope.username} 

  2.与输入有关的隐含对象 

  与输入有关的隐含对象有两个:param和paramValues,它们是EL中比较特别的隐含对象。 

  

  例如我们要取得用户的请求参数时,可以利用下列方法: 

    request.getParameter(String name) 

    request.getParameterValues(String name) 

  在EL中则可以使用param和paramValues两者来取得数据。 

    ${param.name} 

    ${paramValues.name} 

  3.其他隐含对象 

  

  cookie 

  JSTL并没有提供设定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}   取得主机端的服务信息 

三、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)} 

  

四、EL函数(functions)。 

  语法:ns:function( arg1, arg2, arg3 …. argN) 

  其中ns为前置名称(prefix),它必须和taglib 指令的前置名称一置 

--------------------------------------------- 

补充: 

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> 

FOREACH: 

<c:forEach items="${messages}" 

var="item" 

begin="0" 

end="9" 

step="1" 

varStatus="var"> 

…… 

</c:forEach> 

OUT: 

<c:out value="${logininfo.username}"/> 

c:out>将value 中的内容输出到当前位置,这里也就是把logininfo 对象的 

username属性值输出到页面当前位置。 

${……}是JSP2.0 中的Expression Language(EL)的语法。它定义了一个表达式, 

其中的表达式可以是一个常量(如上),也可以是一个具体的表达语句(如forEach循环体中 

的情况)。典型案例如下: 

? ${logininfo.username} 

这表明引用logininfo 对象的username 属性。我们可以通过“.”操作符引 

用对象的属性,也可以用“[]”引用对象属性,如${logininfo[username]} 

与${logininfo.username}达到了同样的效果。 

“[]”引用方式的意义在于,如果属性名中出现了特殊字符,如“.”或者“-”, 

此时就必须使用“[]”获取属性值以避免语法上的冲突(系统开发时应尽量避免 

这一现象的出现)。 

与之等同的JSP Script大致如下: 

LoginInfo logininfo = 

(LoginInfo)session.getAttribute(“logininfo”); 

String username = logininfo.getUsername(); 

可以看到,EL大大节省了编码量。 

这里引出的另外一个问题就是,EL 将从哪里找到logininfo 对象,对于 

${logininfo.username}这样的表达式而言,首先会从当前页面中寻找之前是 

否定义了变量logininfo,如果没有找到则依次到Request、Session、 

Application 范围内寻找,直到找到为止。如果直到最后依然没有找到匹配的 

变量,则返回null. 

如果我们需要指定变量的寻找范围,可以在EL表达式中指定搜寻范围: 

${pageScope.logininfo.username} 

${requestScope.logininfo.username} 

${sessionScope.logininfo.username} 

${applicationScope.logininfo.username} 

在Spring 中,所有逻辑处理单元返回的结果数据,都将作为Attribute 被放 

置到HttpServletRequest 对象中返回(具体实现可参见Spring 源码中 

org.springframework.web.servlet.view.InternalResourceView. 

exposeModelAsRequestAttributes方法的实现代码),也就是说Spring 

MVC 中,结果数据对象默认都是requestScope。因此,在Spring MVC 中, 

以下寻址方法应慎用: 

${sessionScope.logininfo.username} 

${applicationScope.logininfo.username} 

? ${1+2} 

结果为表达式计算结果,即整数值3。 

? ${i>1} 

如果变量值i>1的话,将返回bool类型true。与上例比较,可以发现EL会自 

动根据表达式计算结果返回不同的数据类型。 

表达式的写法与java代码中的表达式编写方式大致相同。 

IF / CHOOSE: 

<c:if test="${var.index % 2 == 0}"> 



</c:if> 

判定条件一般为一个EL表达式。 

<c:if>并没有提供else子句,使用的时候可能有些不便,此时我们可以通过<c:choose> 

tag来达到类似的目的: 

<c:choose> 

<c:when test="${var.index % 2 == 0}"> 



</c:when> 

<c:otherwise> 



</c:otherwise> 

</c:choose> 

类似Java 中的switch 语句,<c:choose>提供了复杂判定条件下的简化处理手法。其 

中<c:when>子句类似case子句,可以出现多次。上面的代码,在奇数行时输出“*”号, 

而偶数行时输出“!”。 

--------------------------------------------- 

再补充: 

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语言可显示 逻辑表达式如${true and false}结果是false    关系表达式如${5>6} 结果是false     算术表达式如 ${5+5} 结果是10

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

OGNL 

OGNL是Object Graph Navigation Language的简称,详细相关的信息可以参考:http://www.ognl.org。这里我们只涉及Struts2框架中对OGNL的基本支持。

OGNL是一个对象,属性的查询语言。在OGNL中有一个类型为Map的Context(称为上下文),在这个上下文中有一个根元素(root),对根元素的属性的访问可以直接使用属性名字,但是对于其他非根元素属性的访问必须加上特殊符号#。

 
当struts2框架接收到一个HTTP请求时,它立刻创建一个ActionContext、ValueStack、Action对象

在Struts2中上下文为ActionContext,根元素位Value Stack(值堆栈,值堆栈代表了一族对象而不是一个对象,其中Action类的实例也属于值堆栈的一个)。ActionContext中的内容如下图:

              | 

              |--application 

              | 

              |--session 

context map---| 

              |--value stack(root) 

              | 

              |--request 

              | 

              |--parameters 

              | 

              |--attr (searches page, request, session, then application scopes) 

              | 

因为Action实例被放在Value Stack中,而Value Stack又是根元素(root)中的一个,所以对Action中的属性的访问可以不使用标记#,而对其他的访问都必须使用#标记。

一个OGNL表达式,必须选择ActionContext中的一个对象作为根对象(root),默认情况下,是选择valueStack作为根对象,如果需要使用另外5个对象作为根对象,需要加上#前缀
 
在<s:>标签的属性里时,要看这个属性定义的类型是什么,如果是string类型,那么属性的值会被当做普通的string,如果不是string类型,那么属性的值会被直接当成OGNL的表达式 

比如说<s:property value="" />,这个标签的value属性的类型是object,那么这个value的值,就会被直接作为OGNL表达式进行解析 

如果想在string类型的属性中使用OGNL表达式,就需要加上${}或者%{} --------------************************取表达式的值

在jsp页面的其他地方时(即不在<s:>标签内部),任何情况下都会当成string来处理,这时候如果想使用OGNL表达式,也需要加上${}或者%{} 

 
*****************************************************举例*******************************************************
 
structs2 中使用el表达式和ognl表达式获得后台实体类中的List值失败
 
<!-----------1--------------------->

<s:iterator value="employee.degreeList" id="degree">

<s:textfield name="employee.degreeList.d_name"  value="${degree.d_name}"><!-----报错,但是${degree.d_name}是可以取到值的,只是我不知道怎么塞到value里---->

<!-----------2--------------------->

<s:iterator value="employee.degreeList" var="degree">

<s:textfield name="employee.degreeList.d_name"  value="#degree.d_name"><!-----取不到值------->

<!-----------3--------------------->

<s:iterator value="employee.degreeList" >

<s:textfield name="d_name" ><!-----这样可以直接实现,但是当在这个页面修改它的值,提交这个表单时,后台获取不到name为d_name这个控件的值,name改为"employee.degreeList.d_name"则好用,但是改成这个用不能显示后台传过来的值------>

java后台实体类中的结构为:有一个employee对象,employee对象中有自己的属性值,另外还有一个名为degreeList的

list对象,该list对象存的是degree实体,degree实体中含有d_name等属性。现在我想通过上面jsp代码(第一种和第二种)得到这个d_name的值,

正解:
<s:iterator value="employee.degreeList" id="degree">

<s:textfield name="employee.degreeList.d_name" value="${degree.d_name}">

${degree.d_name}是EL,不能用在struts2标签里,得用OGNL,试试value="%{#degree.d_name}"

 

引用Action的属性 

<s:property value="postalCode"/> 

ActionContext中的其他非根(root)元素的属性可以按照如下的方式访问: 

<s:property value="#session.mySessionPropKey"/> or 

<s:property value="#session["mySessionPropKey"]"/> or 

<s:property value="#request["mySessionPropKey"]/> 

Action类可以使用ActionContext中的静态方法来访问ActionContext。 

ActionContext.getContext().getSession().put("mySessionPropKey", mySessionObject);

OGNL与Collection(Lists,Maps,Sets) 

生成List的语法为: {e1,e2,e3}. 

<s:select label="label" name="name" 

list="{'name1','name2','name3'}" value="%{'name2'}" /> 

上面的代码生成了一个HTML Select对象,可选的内容为: name1,name2,name3,默认值为:name2。 

生成Map的语法为:#{key1:value1,key2:value2}. 

<s:select label="label" name="name" 

list="#{'foo':'foovalue', 'bar':'barvalue'}" /> 

上面的代码生成了一个HTML Select对象,foo名字表示的内容为:foovalue,bar名字表示的内容为:barvalue。 

判断一个对象是否在List内存在: 

<s:if test="'foo' in {'foo','bar'}"> 

   muhahaha 

</s:if> 

<s:else> 

   boo 

</s:else> 

<s:if test="'foo' not in {'foo','bar'}"> 

   muhahaha 

</s:if> 

<s:else> 

   boo 

</s:else> 

取得一个List的一部分: 

?  –  所有满足选择逻辑的对象 

^  -   第一个满足选择逻辑的对象 

$  -   最后一个满足选择逻辑的对象 

例如: 

person.relatives.{? #this.gender == 'male'} 

上述代码取得这个人(person)所有的男性(this.gender==male)的亲戚(relatives) 

Lambda 表达式 

OGNL支持简单的Lambda表达式语法,使用这些语法可以建立简单的lambda函数。 

例如: 

Fibonacci: 

if n==0 return 0; 

elseif n==1 return 1; 

else return fib(n-2)+fib(n-1); 

fib(0) = 0 

fib(1) = 1 

fib(11) = 89 

OGNL的Lambda表达式如何工作呢? 

Lambda表达式必须放在方括号内部,#this表示表达式的参数。例如: 

<s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)" />

#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)]定义了一个Lambda表达式,

#fib(11) 调用了这个表达式。 

所以上述代码的输出为:89 

在JSP2.1中#被用作了JSP EL(表达式语言)的特殊记好,所以对OGNL的使用可能导致问题, 

一个简单的方法是禁用JSP2.1的EL特性,这需要修改web.xml文件: 

<jsp-config> 

    <jsp-property-group> 

      <url-pattern>*.jsp</url-pattern> 

      <el-ignored>true</el-ignored> 

    </jsp-property-group> 

</jsp-config> 

 
<span >"font-size: large;"><span >"font-size: large;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
<%@ taglib uri="/struts-tags" prefix="s" %>  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
    <title>OGNL的使用</title>  
  </head>  
  <body>  
<h3>OGNL的使用</h3><hr/>  
 访问Action中的普通属性: <s:property value="loginname"/><br/>  
 访问Action中的对象属性: <s:property value="user.birthday"/><br/>  
 访问Action中的Set属性: <s:property value="courseSet.toArray()[0]"/><br/>  
 访问Action中的List属性: <s:property value="list[0]"/><br/>  
 访问Action中的Map属性的键: <s:property value="map.keys.toArray()[1]"/><br/>  
 访问Action中的Map属性的值: <s:property value="map.values.toArray()[1]"/><br/>  
访问Action中的Map属性的指定键对应的值: <s:property value="map['z']"/><br/>   
访问Action中的Map属性的大小: <s:property value="map.size"/><br/>   
<hr/>  
访问ActionContext中的普通属性:<s:property value="#inte"/><br/>  
访问ActionContext中的对象属性:<s:property value="#user2.loginname"/><br/>  
<hr/>  
访问Action中的普通方法:<s:property value="getAppName()"/><br/>  
访问ActionContext中的某个对象上的普通方法:<s:property value="#user2.info()"/><br/>  
<hr/>  
访问静态属性:<s:property value="@java.lang.Math@PI"/><br/>  
访问静态方法:<s:property value="@java.lang.Math@floor(44.56)"/><br/>  
访问Math类中的静态方法:<s:property value="@@floor(44.56)"/><br/>  
<hr/>  
调用java.util.Date的构造方法:<s:date name="new java.util.Date()" format="yyyy-MM-dd HH:mm:ss"/><br/>  
调用java.util.Date的构造方法创建对象,再调用它的方法:<s:property value="new java.util.Date().getTime()"/><br/>  
<hr/>  
投影查询:获取userList中所有loginname的列表:<s:property value="userList.{loginname}"/><br/>  
选择查询:获取userList中所有score大于60的loginname列表:<s:property value="userList.{?#this.score>60.0}.{loginname}"/><br/>  
选择查询:获取userList中所有score大于60并且gender为true的loginname列表:<s:property value="userList.{?(#this.score>60.0 && #this.gender)}.{loginname}"/><br/>  
选择查询:获取userList中所有score大于60并且gender为true的第一个元素的loginname:<s:property value="userList.{^(#this.score>60.0 && #this.gender)}.{loginname}"/><br/>  
选择查询:获取userList中所有score大于60并且gender为true的最后一个元素的loginname:<s:property value="userList.{$(#this.score>60.0 && #this.gender)}.{loginname}"/><br/>  
<hr/>  
访问名为xxx的请求参数对应的第一个值:<s:property value="#parameters.xxx[0]"/><br/>  
访问通过ActionContext中放入Request中的属性:<s:property value="#request.reqAtt"/><br/>  
访问通过ServletActionContext中放入Request中的属性:<s:property value="#request.reqAtt2"/><br/>  
  
访问通过ActionContext中放入Session中的属性:<s:property value="#session.sesAtt"/><br/>  
访问通过ServletActionContext中放入Session中的属性:<s:property value="#session.sesAtt2"/><br/>  
访问通过ActionContext中放入ServletContext中的属性:<s:property value="#application.appAtt"/><br/>  
访问通过ServletActionContext中放入ServletContext中的属性:<s:property value="#application.appAtt2"/><br/>  
  
直接访问属性域中指定名称的属性对应的值:<s:property value="#attr.sesAtt2"/><br/>  
<br/><br/><hr/>  
<s:iterator value="userList" status="vs">  
    <s:if test="%{#vs.odd}">  
        <span >"color: red">  
            <s:property value="#vs.count"/>: <s:property value="loginname"/>,<s:date name="birthday" format="yyyy-MM-dd HH:mm:ss"/><br/>  
        </span>  
    </s:if>  
    <s:else>  
        <span >"color: blue">  
            <s:property value="#vs.count"/>: <s:property value="loginname"/>,<s:date name="birthday" format="yyyy-MM-dd HH:mm:ss"/><br/>  
        </span>  
    </s:else>  
</s:iterator>  
  
<hr/><s:debug/>  
  </body>  
</html></span></span>  
 4.为何使用EL表达式能够访问valueStack中对象的属性

原因是Struts2对HttpServletRequest作了进一步的封装。简略代码如下:

public class StrutsRequestWrapper extends HttpServletRequestWrapper {

public StrutsRequestWrapper(HttpServletRequest req) { 

super(req); 



public Object getAttribute_r(String s) { 

...... 

ActionContext ctx = ActionContext. getContext_r(); 

Object attribute = super. getAttribute_r(s);//先从request范围获取属性值 

if (ctx != null) { 

if (attribute == null) {//如果从request范围没有找到属性值,即从ValueStack中查找对象的属性值 

...... 

ValueStack stack = ctx. getValueStack_r(); 

attribute = stack.findValue(s); 

...... 





return attribute; 



}

5.采用OGNL表达式创建List/Map集合对象

如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。

使用如下代码直接生成一个List对象: 

<s:set name="list" value="{'zhangming','xiaoi','liming'}" /> 

<s:iterator value="#list" id="n"> 

<s:property value="n"/><br> 

</s:iterator>

生成一个Map对象: 

<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" /> 

<s:iterator value="#foobar" > 

<s:property value="key"/>=<s:property value="value"/><br> 

</s:iterator>

Set标签用于将某个值放入指定范围。 

scope:指定变量被放置的范围,该属性可以接受application、session、request、 page或action。如果没有设置该属性,则默认放置在OGNL Context中。

value:赋给变量的值.如果没有设置该属性,则将ValueStack栈顶的值赋给变量。

6.采用OGNL表达式判断对象是否存在于集合中 

对于集合类型,OGNL表达式可以使用in和not in两个元素符号。其中,in表达式用来判断某个元素是否在指定的集合对象中;not in判断某个元素是否不在指定的集合对象中,如下所示。

in表达式: 

<s:if test="'foo' in {'foo','bar'}"> 

在 

</s:if> 

<s:else> 

不在 

</s:else>

not in表达式: 

<s:if test="'foo' not in {'foo','bar'}"> 

不在 

</s:if> 

<s:else> 

在 

</s:else>

7.OGNL表达式的投影功能 

除了in和not in之外,OGNL还允许使用某个规则获得集合对象的子集,常用的有以下3个相关操作符。 

?:获得所有符合逻辑的元素。 

^:获得符合逻辑的第一个元素。 

$:获得符合逻辑的最后一个元素。 

例如代码: 

<s:iterator value="books.{?#this.price > 35}"> 

<s:property value="title" /> - $<s:property value="price" /><br> 

</s:iterator> 

在上面代码中,直接在集合后紧跟.{}运算符表明用于取出该集合的子集,{}内的表达式用于获取符合条件的元素,this指的是为了从大集合books筛选数据到小集合,需要对大集合books进行迭代,this代表当前迭代的元素。本例的表达式用于获取集合中价格大于35的书集合。

public class BookAction extends ActionSupport { 

private List<Book> books; 

.... 

@Override 

public String execute() { 

books = new LinkedList<Book>(); 

books.add(new Book("A735619678", "spring", 67)); 

books.add(new Book("B435555322", "ejb3.0",15)); 



}

8.property标签 

property标签用于输出指定值: 

<s:set name="name" value="'kk'" /> 

<s:property value="#name"/> 

default:可选属性,如果需要输出的属性值为null,则显示该属性指定的值 

escape:可选属性,指定是否格式化HTML代码。 

value:可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值。 

id:可选属性,指定该元素的标识

9. iterator标签 

iterator标签用于对集合进行迭代,这里的集合包含List、Set和数组。 

<s:set name="list" value="{'zhangming','xiaoi','liming'}" /> 

<s:iterator value="#list" status="st"> 

<font color=<s:if test="#st.odd">red</s:if><s:else>blue</s:else>> 

<s:property /></font><br> 

</s:iterator> 

value:可选属性,指定被迭代的集合,如果没有设置该属性,则使用ValueStack栈顶的集合。 

id:可选属性,指定集合里元素的id。 

status:可选属性,该属性指定迭代时的IteratorStatus实例。该实例包含如下几个方法: 

int getCount_r(),返回当前迭代了几个元素。 

int getIndex_r(),返回当前迭代元素的索引。 

boolean isEven(),返回当前被迭代元素的索引是否是偶数 

boolean isOdd(),返回当前被迭代元素的索引是否是奇数 

boolean isFirst(),返回当前被迭代元素是否是第一个元素。 

boolean isLast(),返回当前被迭代元素是否是最后一个元素。

10.if/elseif/else标签 

<s:set name="age" value="21" /> 

<s:if test="#age==23"> 

23 

</s:if> 

<s:elseif test="#age==21"> 

21 

</s:elseif> 

<s:else> 

都不等 

</s:else>

10.url标签

<s:url action="helloworld_add" namespace="/test"><s:param name="personid" value="23"/></s:url>

生成类似如下路径: 

/struts/test/helloworld_add.action?personid=23 

红色部分为内容路径。

标签的属性值作为字符串类型处理时, “%”符号的用途是计算OGNL表达式的值。 

<s:set name="myurl" value="'http://www.foshanshop.net'"/> 

<s:url value="#myurl" /><br> 

<s:url value="%{#myurl}" /> 

输出结果: 

#myurl 
http://www.foshanshop.net
11.表单标签_checkboxlist复选框

如果集合为list 

<s:checkboxlist name="list" list="{'Java','.Net','RoR','PHP'}" value="{'Java','.Net'}"/>

生成如下html代码: 

<input type="checkbox" name="list" value="Java" checked="checked"/><label>Java</label>

<input type="checkbox" name="list" value=".Net" checked="checked"/><label>.Net</label>

<input type="checkbox" name="list" value="RoR"/><label>RoR</label> 

<input type="checkbox" name="list" value="PHP"/><label>PHP</label>

如果集合为MAP 

<s:checkboxlist name="map" list="#{1:'瑜珈用品',2:'户外用品',3:'球类',4:'自行车'}" listKey="key" listValue="value" value="{1,2,3}"/>

生成如下html代码: 

<input type="checkbox" name="map" value="1" checked="checked"/><label>瑜珈用品</label>

<input type="checkbox" name="map" value="2" checked="checked"/><label>户外用品</label>

<input type="checkbox" name="map" value="3" checked="checked"/><label>球类</label> 

<input type="checkbox" name="map" value="4"/><label>自行车</label>

12. 表单标签_checkboxlist复选框 

如果集合里存放的是javabean 

<% 

Person person1 = new Person(1,"第一个"); 

Person person2 = new Person(2,"第二个"); 

List<Person> list = new ArrayList<Person>(); 

list.add(person1); 

list.add(person2); 

request.setAttribute("persons",list); 

%> 

<s:checkboxlist name="beans" list="#request.persons" listKey="personid" listValue="name"/>

Personid和name为Person的属性

生成如下html代码: 

<input type="checkbox" name=“beans" value="1"/><label>第一个</label> 

<input type="checkbox" name=“beans" value="2"/><label>第二个</label>

13.表单标签_radio单选框 

标签的使用和checkboxlist复选框相同。 

如果集合里存放的是javabean(personid和name为Person的属性) 

< s:radio name="beans" list="#request.persons" listKey="personid" listValue="name"/>

生成如下html代码: 

<input type="radio" name="beans" id="beans1" value="1"/><label>第一个</label> 

<input type="radio" name="beans" id="beans2" value="2"/><label>第二个</label> 

如果集合为MAP 

<s:radio name="map" list="#{1:'瑜珈用品',2:'户外用品',3:'球类',4:'自行车'}" listKey="key" listValue="value“ value="1"/>

生成如下html代码: 

<input type="radio" name="map" id="map1" value="1"/><label for="map1">瑜珈用品</label>

<input type="radio" name="map" id="map2" value="2"/><label for="map2">户外用品</label>

<input type="radio" name="map" id="map3" value="3"/><label for="map3">球类</label> 

<input type="radio" name="map" id="map4" value="4"/><label for="map4">自行车</label>

如果集合为list 

<s:radio name="list" list="{'Java','.Net'}" value="'Java'"/> 

生成如下html代码: 

<input type="radio" name="list" checked="checked" value="Java"/><label>Java</label>

<input type="radio" name="list" value=".Net"/><label>.Net</label>

14.表单标签_select下拉选择框 

<s:select name="list" list="{'Java','.Net'}" value="'Java'"/> 

<select name="list" id="list"> 

<option value="Java" selected="selected">Java</option> 

<option value=".Net">.Net</option> 

</select> 

<s:select name="beans" list="#request.persons" listKey="personid" listValue="name"/>

<select name="beans" id="beans"> 

<option value="1">第一个</option> 

<option value="2">第二个</option> 

</select> 

<s:select name="map" list="#{1:'瑜珈用品',2:'户外用品',3:'球类',4:'自行车'}" listKey="key" listValue="value" value="1"/>

<select name="map" id="map"> 

<option value="1" selected="selected">瑜珈用品</option> 

<option value="2">户外用品</option> 

<option value="3">球类</option> 

<option value="4">自行车</option> 

</select>

 

总结:

在上边大家都好奇为什么都用struts的S[b]标签,因为OGNL是通常要结合Struts 2的标志一起使用,如<s:property value="xx" />等[/b]

 Action类与JSP页面之间的数据传递

 1) 通过HttpServletRequest,HttpSession,ServletContext来传递数据。

    a) Action中传数据:在Action类的请求处理方法中先获取各个作用域对象

    ServletActionContext.getRequest();

    ServletActionContext.getRequest().getSession();

    ServletActionContext.getServletContext();

          然后调用相应的setAttribute(String "键", Object 值);

    b) 在JSP页面中取数据:可以使用EL表达式或代码片段来取出对应作用域中属性值。

    c) 页面中的请求参数传递到Action中时,Action中直接定义对应名称的属性,并提供setter方法即可封装此数据。

    

 2) 通过ActionContext实例来传递数据。 ActionContext针对每个正在执行Action的线程中绑定一份。

   a) Action中通过ActionContext传递数据。

      ActionContext提供了put(String "键", Object 值);  //数据不会映射到HttpServletRequest中。

      ActionContext提供的getSession().put(String "键", Object 值);  //数据会自动映射到HttpSession中。

      ActionContext提供的getApplication().put(String "键", Object 值); //数据会自动映射到ServletContext中。

   b) 在JSP页面取数据:struts2推荐使用OGNL来取ActionContext中的数据。

 

1. Struts2中的OGNL的使用。

2. OGNL:对象图导航语言。通过OGNL表达式可以获取对象的属性,调用对象的方法,或构造出对象。

  1) OGNL上下文中有一个根对象。这个根对象可以直接获取。不需要#。

  2)支持常量:

         字符串常量、字符常量、

         数值常量:int、long、float、double

         布尔常量:true、false

    Null常量 : null

         支持操作符:支持Java的所有操作符,还支持特有的操作符: ,、 {}、in、not in;

 Struts2中的OGNL:

  1) Struts2将ActionContext设置为OGNL上下文,并将值栈(ValueStack)作为OGNL的根对象放置到ActionContext中。

  2) Struts2总是把当前Action实例放置在值栈的栈顶。所以,在OGNL中引用Action中的属性也可以省略“#”。

   常用[b]标签[/b]

 1) <s:property value="OGNL"/>

 2) <s:date name="OGNL" format=""/>

 3) <s:if test="OGNL"></s:if><s:elseif test="OGNL"></s:elseif><s:else></s:else>

★4) <s:iterator value="OGNL" status="vs">...</s:iterator>

 5) <s:debug/>

 

6、关于JSP的 默认语法、EL、Ognl表达式,Struts Tag 和JSTL[b]标签库等 [/b]

JavaWeb 默认的语法,除HTML 外,共有:

1、<% 可以使用Java语言 %>

2、<%!  可以使用Java 语言定义变量或函数,是public 类型的 %>

3、<%= 变量 %> 可以取值

4、<%@  指令元素  %>

5、<jsp:include、forward  …… ></jsp:include、forward> 默认标签语言

 以上五种是Javaweb 默认语法,除第五种是标签语言外,其余上四种都是JavaWeb 默认的语法格式。

 此后,JSP2.0之后,引入了 EL 表达语言和 扩展了 标签语言 称为:JSTL 。

 EL 表达式语言,其实可以说是一套独立的编程语言,有自己的语法格式,算式运算符,关系运算符,逻辑运算符,条件运算符等等完整的体系,加上还有一些内置的对象,虽然这些内置的对象都需要Java 支持,但也不失为一套完善的编程语言了。

 EL 主要编写在 后缀为.jsp 的页面中,虽然它有自己的语法格式,但其实它的本质是Java类,它会通过Web容器转为特定的Java代码,而后运行在Java虚拟机中,只是为了规范 和方便,所以SUN公司推出了它,但发展到现在,它已经称为JavaWeb不可分割的一部分(虽然JSP页面如今少写业务逻辑)

 JSTL 是 JSP2.0 后引入的默认标签库,记得默认语法中,第五条就是 <jsp:xxx /> ,而JSTL可以说是那个的升级版,增加了很多可以直接在 jsp 页面中使用,而格式跟普通HTML类似的标签

 接下来,谈谈,Struts2.x 中的OGNL  表达式 和 标签 Struts Tag 。

 Struts2.x 中的 OGNL 可以说是取代了 默认的EL表达式,它自身本就是 EL 表达式,它与默认的EL表达式语言,区别共有多少,我没有仔细去了解,只能说说大致了解的。

1、  取值范围:

a)         默认的EL表达式的格式 ${ },它能单独使用,默认取值范围在 :page (PageContext)

b)        OGNL 表达式常用的格式为 # ,还有 $ % 等,默认的取值范围是:valueStack 值栈。

2、   使用范围

a)         默认的EL表达式能单独使用。

b)        OGNL 需要和 标签 Struts Tag 联合使用

3、  优势

a)         EL 表达式 在于有完整的体系,功能完善,

b)        OGNL 没有那些运算,关系,条件,逻辑等等运算符,但它在于能单独访问对象(类),包括静态类,静态方法等

4、  搭档

a)         EL + JSTL 。默认的EL虽然能完成大部分功能,但天生缺少的一些,比如遍历等,就需要配合JSTL使用,功能更为完善。

b)        OGNL + Struts Tag 。OGNL 负责取值,Struts Tag 负责控制流程。分工明确!

 

Struts 2.x 的 Struts Tag ,是Struts 默认的标签库,和OGNL 一起使用功能更强大。一般来说,OGNL 取值,而Struts Tag 控制流程和显示。

它取代了 默认的JSTL标签库。

 7、struts2中#、%和$这三个符号的使用方法 

一、"#"的用法 

   1、 访问OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个ActionContext中有用的属性: 

 名称作用例子
parameters包含当前HTTP请求参数的Map#parameters.id[0]作用相当于request.getParameter("id")
request包含当前HttpServletRequest的属性(attribute)的Map#request.userName相当于request.getAttribute("userName")
session包含当前HttpSession的属性(attribute)的Map#session.userName相当于session.getAttribute("userName")
application包含当前应用的ServletContext的属性(attribute)的Map#application.userName相当于application.getAttribute("userName")
attr用于按request > session > application顺序访问其属性(attribute)#attr.userName相当于按顺序在以上三个范围(scope)内读取userName属性,直到找到为
 2、用于过滤和投影(projecting)集合,如books.{?#this.price<100}; 

     3、构造Map,如#{'foo1':'bar1', 'foo2':'bar2'}。 

二、"%"的用法 

    “%”符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。例如在Ognl.jsp中加入以下代码: 

    <h3>%的用途</h3> 

    <p><s:url value="#foobar['foo1']" /></p> 

    <p><s:url value="%{#foobar['foo1']}"/></p> 

三、"$"的用法 

    1、用于在国际化资源文件中,引用OGNL表达式 

    2、在Struts 2配置文件中,引用OGNL表达式 

     例如: 

         <action name="AddPhoto" class="addPhoto"> 

            <interceptor-ref name="fileUploadStack" />            

            <result type="redirect">ListPhotos.action?       albumId=${albumId}</result> 

        </action>

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐