用ognl还是jstl+el?

Struts 推荐使用功能更加强大的 Ognl 表达式。 El 可以完成的功能, Ognl 也可以, El 不能完成的功能, Ognl 也可以。
但是有些程序员,已经习惯了jsp中结合jstlel表达式,我们可以有两种解决方案:
1. 使用struts2自带的标签库,jsp中使用ognl进行操作。
2. 不是用struts2自带的标签库,jsp直接结合jstl+el进行操作。
jsp2.0 中默认启动对el表达式的支持的。但从Struts2.0.11起,Struts2标签库将不再支持El表达式。
struts2.0.11 版本不支持el,因而以前在低版本下写和程式将不能正常运行:
下面是一段分页所用的循环:
<c:forEach var="i" begin="1" end="${requestScope.page.afterPage}" step="1">
    <c:if
     test="${requestScope.page.indexPage<requestScope.page.totalPage && requestScope.page.indexPage+i<requestScope.page.totalPage}">
     <s:url id="afterUrl" value="/photoItemsList.html">
          <s:param name="indexPage" value="${requestScope.page.indexPage+i}" /><!-- struts2.0.11 中已不支持el,因而<s:url>将取不到相关值-->
     </s:url>
     <s:a theme="ajax" href="%{afterUrl}" indicator="indicator" showLoadingText="false" targets="pageItems">
          <c:out value="${requestScope.page.indexPage+i}" />&nbsp;</s:a>
    </c:if>
   </c:forEach>
修改成如下:
<c:forEach var="i" begin="1" end="${requestScope.page.afterPage}" step="1">
    <c:set value="${i}" var="var"/>
    <c:if   test="${requestScope.page.indexPage<requestScope.page.totalPage && requestScope.page.indexPage+i<requestScope.page.totalPage}">
     <s:url id="afterUrl" value="/photoItemsList.html">
          <s:param name="indexPage" value="#request.page.indexPage+#attr.var" />
     </s:url>
     <s:a theme="ajax" href="%{afterUrl}" indicator="indicator" showLoadingText="false" targets="pageItems">
          <c:out value="${requestScope.page.indexPage+i}" />&nbsp;</s:a>
    </c:if>
   </c:forEach>
但我们使用第二种方式时,el可以访问struts2valuestack中的值。
El 表达式使用,还是像以前一样的,但是 struts2 中添加了一个值栈对象,所以有些小小的变动,搜索的顺序是 Page Reqeust ValueStack Session Application
值栈中存储的是 Action 类中的全局变量(在 servlet struts 中是不支持直接读取 Action 类中的值得,要设置到 Request Session 等中,进行值得传递)。
测试程序(服务器端):
package com.helloweenvsfei.struts2.action;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
 
import org.apache.struts2.ServletActionContext;
 
import com.opensymphony.xwork2.ActionSupport;
 
public class OgnlElAction extends ActionSupport{
 /**
        *
        */
       private static final long serialVersionUID = 1L;
       private int i;// 来自客户端,能取得
       private String j;// 额外定义,能取得
       private String c="C";// 没有 get set 方法, EL 不能获取
       public String getJ() {
              j="J";
              return j;
       }
      
       public void setJ(String j) {
              this.j = j;
       }
      
       @Override
       public String execute() throws Exception {
              i=i+100;
              String a="wla";// 不能获取,除非设值到 request 等范围
              String b="wlb";// 不能获取,除非设值到 request 等范围
             
              HttpServletRequest request=ServletActionContext.getRequest();
       //    request.setAttribute("a", "locala");
       //    HttpSession session=request.getSession();
       //    session.setAttribute("b", "localb");
       // 要是在取值是没有响应的属性,就是默认值。
              request.setAttribute("f", "localf");
              request.setAttribute("d", "four local");
              HttpSession session=request.getSession();
              session.setAttribute("d", "locald");
       //    以上三句说明,是按照顺序进行查找的。
              //request.setAttribute("j", "action");
              //session.setAttribute("j", "action");
       // 总结出 EL 的访问顺序, Page Request ValueStack Session Application
      
              return SUCCESS;
       }
      
       public int getI() {
             
              return i;
       }
      
       public void setI(int i) {
              this.i = i;
       }
}
客户端:
<body>
<%--  <% String j="page"; %>
<% pageContext.setAttribute("j","MLDN") ;
%>
--%>
    This is my JSP page. <br>
    Action:${i};<br/>
    Action:${j};<br/>
    Action:${c};<br/>
    Execute:${requestScope.a};<br/>
    Execute:${sessionScope.b};<br/>
    Execute:${d};<br/>
    Execute:${f};<br/>
<!--  Execute:${requestScope.a};
    Execute:${sessionScope.b}; -->
<!--<s:property value="#session.i"/>-->
</body>
 
关于OGNL
OGNL 全称为Object-Graph Navigation Language,是一种表达式语言(EL)。
EL 的支持者认为,在JSP页面中应尽可能地避免 <% %> 这样的标记,而代之以Tag,以使页面更简洁,并体现页面与后台代码分离的设计原则。对此我持保留意见,因为我并不认为使用Tag后的页面的可读性要高于使用<% %>
Struts 2 支持如下几种EL
        OGNL(Object-Graph Navigation Language): 可以方便地操作对象属性的开源表达式语言
        JSTL(JSP Standard Tag Library): JSP 2.0 集成的标准的表达式语言
        Groovy: 基于Java平台的动态语言,它具有时下比较流行的动态语言(如PythonRubySmarttalk等)的一些新特性
        Velocity: 严格来说不是表达式语言,它是一种基于Java的模板匹配引擎,据说其性能要比JSP
 
Struts 2 默认的表达式语言是OGNL,原因是它相对其它表达式语言具有下面几大优势:
        支持对象方法调用,如xxx.doSomeSpecial()
        支持类静态的方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 | 值名],例如: @java.lang.String@format('foo %s', 'bar') @tutorial.MyConstant@APP_NAME
        支持赋值操作和表达式串联,如price=100, discount=0.8, calculatePrice(),这个表达式会返回80
        访问OGNL上下文(OGNL context)和ActionContext
        操作集合对象。
 
OGNL 是通常要结合Struts 2的标志一起使用,如<s:property value="xx" />等。大家经常遇到的问题是#%$这三个符号的使用。下面我讲述这个问题:
 
4.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)的Ma #session.userName相当于session.getAttribute("userName")
        application :包含当前应用的ServletContext的属性(attribute)的Map#application.userName相当于application.getAttribute("userName")
        attr :用于按request > session > application顺序访问其属性(attribute),#attr.userName相当于按顺序在以上三个范围(scope)内读取userName属性,直到找到为止
 
过滤和投影(projecting)集合
books.{?#this.price<100}
构造Map
#{'foo1':'bar1', 'foo2':'bar2'}
 
4.2 % 的用法
“%” 符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。例如在Ognl.jsp中加入以下代码:
<h3>% 的用途</h3><p><s:url value="#foobar['foo1']" /></p><p><s:url value="%{#foobar['foo1']}" /></p>
刷新页面,显示以下内容
% 的用途#foobar['foo1']bar1
 
4.3 $ 的用法
“$” 有两个主要的用途:
1.  用于在国际化资源文件中,引用OGNL表达式
2.  Struts 2 配置文件中,引用OGNL表达式,如
 
<action name="AddPhoto" class="addPhoto"> <interceptor-ref name="fileUploadStack" /> <result type="redirect">ListPhotos.action?albumId=${albumId}</result></action>
 
 
 

你可能感兴趣的:(java,职场,EL,jstl,Ognl,休闲)