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平台的动态语言,它具有时下比较流行的动态语言(如Python、Ruby和Smarttalk等)的一些新特性
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'}

在此我演示一下这三种用途:

Book.java
这是一个Bean,用于描述一本书的信息

package example;public class Book {    private String isbn;    private String title;    private double price;        public Book() {            }        public Book(String isbn, String title, double price) {        this.isbn = isbn;        this.title = title;        this.price = price;    }    public String getIsbn() {        return isbn;    }    public void setIsbn(String isbn) {        this.isbn = isbn;    }    public double getPrice() {        return price;    }    public void setPrice(double price) {        this.price = price;    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    }
BookDao.java
一个伪DAO类

package example;import java.util.Collection;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;public class BookDao {    private static final BookDao instance;    private static final ConcurrentMap<String, Book> data;        static {        instance = new BookDao();        data = new ConcurrentHashMap<String, Book>();        data.put("978-0735619678", new Book("978-0735619678", "Code Complete, Second Edition", 32.99));        data.put("978-0596007867", new Book("978-0596007867", "The Art of Project Management", 35.96));        data.put("978-0201633610", new Book("978-0201633610", "Design Patterns: Elements of Reusable Object-Oriented Software", 43.19));        data.put("978-0596527341", new Book("978-0596527341", "Information Architecture for the World Wide Web: Designing Large-Scale Web Sites", 25.19));        data.put("978-0735605350", new Book("978-0735605350", "Software Estimation: Demystifying the Black Art", 25.19));    }        private BookDao() {}        public static BookDao getInstance() {        return instance;    }        public Collection<Book> getBooks() {        return data.values();    }        public Book getBook(String isbn) {        return data.get(isbn);    }        public void storeBook(Book book) {        data.put(book.getIsbn(), book);    }            public void removeBook(String isbn) {        data.remove(isbn);    }        public void removeBooks(String[] isbns) {        for(String isbn : isbns) {            data.remove(isbn);        }    }}
OgnlAction.java
演示OGNL的Servlet类

package example;import java.util.LinkedList;import java.util.List;import java.util.Map;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.interceptor.ServletRequestAware;import org.apache.struts2.interceptor.SessionAware;import org.apache.struts2.util.ServletContextAware;import com.opensymphony.xwork2.ActionSupport;public class OgnlAction extends ActionSupport implements ServletRequestAware, SessionAware, ServletContextAware  {    private static final long serialVersionUID = 1L;        private HttpServletRequest request;    private Map<String, String> session;    private ServletContext application;    private List<Book> books;                public void setServletRequest(HttpServletRequest request) {        this.request = request;        }    @SuppressWarnings("unchecked")    public void setSession(Map session) {        this.session = session;            }    public void setServletContext(ServletContext application) {        this.application = application;    }        public List<Book> getBooks() {        return books;    }    @Override    public String execute() {        request.setAttribute("userName", "Max From request");        session.put("userName", "Max From session");        application.setAttribute("userName", "Max From application");                books = new LinkedList<Book>();        books.add(new Book("978-0735619678", "Code Complete, Second Edition", 32.99));        books.add(new Book("978-0596007867", "The Art of Project Management", 35.96));        books.add(new Book("978-0201633610", "Design Patterns: Elements of Reusable Object-Oriented Software", 43.19));        books.add(new Book("978-0596527341", "Information Architecture for the World Wide Web: Designing Large-Scale Web Sites", 25.19));        books.add(new Book("978-0735605350", "Software Estimation: Demystifying the Black Art", 25.19));                return SUCCESS;    }}
Ognl.jsp
演示OGNL的JSP

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %><%@ taglib prefix="s" uri="/struts-tags" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>    <title>Struts OGNL Demo</title></head><body>        <h3>访问OGNL上下文和Action上下文</h3>    <p>parameters: <s:property value="#parameters.userName" /></p>    <p>request.userName: <s:property value="#request.userName" /></p>    <p>session.userName: <s:property value="#session.userName" /></p>    <p>application.userName: <s:property value="#application.userName" /></p>    <p>attr.userName: <s:property value="#attr.userName" /></p>    <hr />    <h3>用于过滤和投影(projecting)集合</h3>    <p>Books more than $35</p>    <ul>        <s:iterator value="books.{?#this.price > 35}">            <li><s:property value="title" /> - ___FCKpd___3lt;s:property value="price" /></li>        </s:iterator>    </ul>    <p>The price of "Code Complete, Second Edition" is: <s:property value="books.{?#this.title=='Code Complete, Second Edition'}.{price}[0]"/></p>    <hr />    <h3>构造Map</h3>    <s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />    <p>The value of key "foo1" is <s:property value="#foobar['foo1']" /></p></body></html>
example.xml
struts2 的MVC配置文件

<action name="Ognl" class="example.OgnlAction"> <result>/Ognl.jsp</result></action>

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 $的用法
“$”有两个主要的用途:

用于在国际化资源文件中,引用OGNL表达式
Struts 2配置文件中,引用OGNL表达式,如
<action name="AddPhoto" class="addPhoto"> <interceptor-ref name="fileUploadStack" />             <result type="redirect">ListPhotos.action?albumId=${albumId}</result></action>

你可能感兴趣的:(Web,jsp,struts,servlet,groovy)