问题?OGNL表达式,什么事OGNL表达式呢?
1.定义:OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。总而言之一句话,想对EL表达式在四大域中获取对象,OGNL表达式可直接在动作类中直接获取属性值。
注:要使用ognl表达式首先得配置好struts2环境
OGNL是从ActionContext中获取数据的。
ActionContext的结构:
ValueStack:
List:动作类放在此处。取存放在ValueStack中的root的对象的属性,直接写即可
访问以下内容中的对象要使用#+(范围)session
application:ServletContext中的那个Map
session:HttpSession中的那个Map
request:ServletRequest中的那个Map
parameters:请求参数的那个Map。(如同EL表达式的paramValues内置对象)
attr:相当于PageContext的findAttribute方法。${username}
小技巧:在页面中使用<s:debug/>查看上下文中的对象
2.通过一系列的图片对OGNL表达式来了解下。
要注意的是上下文的MAP结构喔!
首先是上面标注的根对象:value stack,在value stack中action实例的对象,可以直接由OGNL表达式访问。
注:普通的valuestack值栈中的对象在s标签中不用加#获取,而另外的一些对象就需要了。若是不清楚,我们时常在页面写<s:debug></s:debug>这个标签来常看相关的存储对象在哪儿。
然后我们来理解一下,它是如何将动作类中的独显存储到valuestack中的。(实际上就是对HttpRequest进一步的封装。)要求理解
对于这些属性的访问,我们用案例来说明下(Struts2环境下,如何配置详情在我的另外一篇文章:点击打开链接):
首先是配置struts.xml文件中的动作action
<?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> <!-- constant表示常量设置,设置配置文件自动更新,开发中很重要 --> <constant name="struts.action.extension" value="action,,do"></constant> <constant name="struts.devMode" value="true"></constant> <package name="ognl" extends="struts-default"> <action name="a1" class="cn.itcast.web.domain.PersonAction"> <result name="success">/a1.jsp</result> </action> </package> </struts>
package cn.itcast.web.domain; import java.io.Serializable; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class PersonAction extends ActionSupport implements Serializable { private String username; private int age; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String execute(){ username="Mr_Li13"; age=18; ServletActionContext.getRequest().setAttribute("username", "aaaa"); ActionContext.getContext().put("sess", "ssss"); ActionContext.getContext().getSession().put("sess", "得到session设置的值"); return SUCCESS; } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'a1.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <s:property value="[0].username"/> <br/> <s:property value="age"/> <br/> <s:property value="locale"/><br/> <!-- 域对象用#来取 --> <s:property value="#session.sess"/><br/> <s:property value="#attr.sess"/> <!-- attr这个代表的是在域对象中去找sess, 按page-request-session-application的顺序找,找到了就停止 --> <hr> <!-- 下面这个username的说明,只是说username只能在所在的域里面去寻找该属性。 不比ognl表达式,它是直接才动作类里去取属性值 ,从而说明了,el表达式的作用于值在11大隐含对象中。 --> ${username }<br> ${sessionScope.sess }<br> ${sess }<br><!-- 作用和attr一样,依次寻找 --> <s:debug></s:debug> </body> </html>
结果:没有经过acting动作类的属性值,是得不到访问的。(因为没有存再valuestack中)
创建map、list
案例:jsp页面代码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/struts-tags" prefix="s"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'ognl1.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <div align="center" style="text-align: center;"> <h2 align="center">This is my JSP page.</h2> <br> <s:set var="list1" value="{'a','b','c'}"></s:set><!-- 默认放到Actioncontext上下文件中 --><br> <s:set var="list2" value="{'11','22','33'}" scope="session"></s:set> <!-- 遍历list session范围同理--> <s:iterator value="#list1" var="c" > <s:property value="#c"/> </s:iterator> <br> <s:property value="#list1[0]"/><br> <s:property value="#session.list2[0]"/><br> <hr> <!-- 设置map值,切遍历它或者单独取值 --> <s:set var="map1" value="#{'a':'a的值','b':'b的值' }" scope="session"></s:set> <!-- 运用迭代器,如图EL表达式中的<c:forEach > --> <s:iterator value="#session.map1" var="map"> <s:property value="#map.key"/>=<s:property value="#map.value"/><br> </s:iterator> <!--${map1['a'] } 证明取不出来 --> <hr> <!-- in 和 not in 的使用方法 --> <s:if test=" 'MM' in {'MM','DD','GG'}" > 在三者中 </s:if> <s:debug></s:debug> </div> </body> </html>
ognl的投影技术:
案例:
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> <!-- constant表示常量设置,设置配置文件自动更新,开发中很重要 --> <constant name="struts.action.extension" value="action,,do"></constant> <constant name="struts.devMode" value="true"></constant> <package name="ognl1" extends="struts-default"> <action name="a2" class="cn.itcast.web.domain.BookAction" method="showAllBooks"> <result name="success">/ognl2.jsp</result> </action> </package> </struts>
package cn.itcast.web.domain; import java.io.Serializable; public class Book implements Serializable { private String name; private float price; public Book(){ } public Book(String name, float price) { super(); this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } }
package cn.itcast.web.domain; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import com.opensymphony.xwork2.ActionSupport; public class BookAction extends ActionSupport implements Serializable { private List<Book> books; public List<Book> getBooks() { return books; } public void setBooks(List<Book> books) { this.books = books; } public String showAllBooks(){ //从数据库中查出来 books = new ArrayList<Book>(); books.add(new Book("葵花宝典", 8.00f)); books.add(new Book("玉女心经", 18.00f)); books.add(new Book("辟邪剑法", 38.00f)); return SUCCESS; } }
<%@ taglib uri="/struts-tags" prefix="s"%> <body> <s:iterator value="books.{?#this.price>10}" var="book"> <s:property value="#book.name"/> <s:property value="#book.price"/><br/> </s:iterator> </body>
该案例的下载:点击打开链接