问题?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>
然后是action动作类,PersonAction.class
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;
}
}
然后我建立jsp页面得到这些对象的值,包括域对象和属性值(首先导入/struts-tags标签库)
<%@ 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>
bean类:Book.class
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;
}
}
BookAction.class动作类
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;
}
}
jsp页面
<%@ 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>
效果:
该案例的下载:点击打开链接