zoukankan      html  css  js  c++  java
  • 20160502-struts2入门--ognl表达式

    一、OGNL表达式语言
    OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts 2框架使用OGNL作为默认的表达式语言。
     
    相对EL表达式,它提供了平时我们需要的一些功能,如:
    ①支持对象方法调用,如xxx.sayHello();
    ②支持类静态方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 |  值名],例如:@java.lang.String@format('foo %s', 'bar')或@cn.itcast.Constant@APP_NAME;
    ③操作集合对象。
    Ognl 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext,下面是上下文(Context)的结构示意图
     
    Struts 2中的OGNL Context实现者为ActionContext,它结构示意图如下:
    当Struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action 。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。
    访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session
     
    另外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"/>
     
    由于ValueStack(值栈)是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性:
    ${foo} //获得值栈中某个对象的foo属性
     
    如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。
    application对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用ServletContext的getAttribute("username")。
     
    session对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。
     
    request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.getAttribute("userName")。
     
    parameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。
     
    attr对象:用于按page->request->session->application顺序访问其属性。
     
    为何使用EL表达式能够访问valueStack中对象的属性
    原因是Struts2对HttpServletRequest作了进一步的封装。简略代码如下:
    public class StrutsRequestWrapper extends HttpServletRequestWrapper {
           public StrutsRequestWrapper(HttpServletRequest req) {
               super(req);
           }
           public Object getAttribute(String s) {
            ......
            ActionContext ctx = ActionContext.getContext();
            Object attribute = super.getAttribute(s);//先从request范围获取属性值
            if (ctx != null) {
                if (attribute == null) {//如果从request范围没有找到属性值,即从ValueStack中查找对象的属性值
                   ......
                   ValueStack stack = ctx.getValueStack();
                   attribute = stack.findValue(s);
                   ......
                }
            }
            return attribute;
        }
     }
    采用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栈顶的值赋给变量。
     
    采用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>
    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));
        }
    }

     示例代码:

    book.java

    package com.dzq.domain;
    
    public class Book {
        private int bookid;
        private String name;
        private int price;
    
        public int getBookid() {
            return bookid;
        }
    
        public void setBookid(int bookid) {
            this.bookid = bookid;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getPrice() {
            return price;
        }
    
        public void setPrice(int price) {
            this.price = price;
        }
    
        public Book(int bookid, String name, int price) {
            this.bookid = bookid;
            this.name = name;
            this.price = price;
        }
    
    }

    PersonListAction.java

    package com.dzq.action;
    
    import java.util.*;
    
    import com.dzq.domain.Book;
    
    public class PersonListAction {
        private String name;
        private List<Book> books;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        
        
        
        
        public List<Book> getBooks() {
            return books;
        }
    
        public void setBooks(List<Book> books) {
            this.books = books;
        }
    
        public String execute(){
            books=new ArrayList<Book>();
            books.add(new Book(1, "黑客与画家", 23));
            books.add(new Book(2, "傲慢与偏见", 35));
            books.add(new Book(3, "春娇与志明", 45));
            name="小明";
            return "list";
        }
    }

    struts.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
    
    <struts>
      <package name="dzq" namespace="/dzq" extends="struts-default">
          <action name="list" class="com.dzq.action.PersonListAction">
              <result name="list">/WEB-INF/page/personlist.jsp</result>
          </action>
      </package>
    </struts>

    index.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
        <%
        request.setAttribute("user", "xiaoduc");
        request.getSession().setAttribute("user", "hello");
        %>
    <%@taglib uri="/struts-tags" prefix="s"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <s:property value="#request.user"/><br>
        <s:property value="#session.user"/><br>
        
        <s:set var="list" value="{'第一个','第二个','第三个'}" />
        <s:iterator value="#list">
        <s:property/><br>
        </s:iterator>
        <s:set var="maps" value="#{'key1':90,'key2':35,'key3':40 }" />
        <s:iterator value="#maps">
        <s:property value="key" />= <s:property value="value"/><br>
        </s:iterator>
        
        <s:if test="'foo' in {'foo','value'}"></s:if>
        <s:else>
        不在
        </s:else>
        
        
    </body>
    </html>

    personlist.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
        <%@taglib uri="/struts-tags"  prefix="s" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <s:property value="name"/>
    ${name }<br>
    <s:iterator value="books.{?#this.price>30}" >
    书名:<s:property value="name"/><br>
    价格:<s:property value="price"/><br>
    <hr>
    </s:iterator>
    </body>
    </html>
  • 相关阅读:
    5月29日实验报告
    实验报告(2019年4月30日)下半部分
    实验报告(2019年4月31日)
    实验报告(2019年4月17日)
    第五章 循环结构课后反思
    实验报告(2019年4月3日)
    第一次实验报告
    503小组第三章编程作业
    第九章 结构体与共用体
    第八章 指针实验
  • 原文地址:https://www.cnblogs.com/xiaoduc-org/p/5453099.html
Copyright © 2011-2022 走看看