1.OGNL表达式
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写, 是一个使用简单,功能强大的,开源的表达式语言, 可以方便地操作任何对象属性,方法等. Struts2框架使用OGNL作为默认的表达式语言, 主要用于页面的取值. 它类似于EL表达式语言, 但比EL语法强大很多
用法:
OGNL是类似于EL的, 用于页面上取后台的值, 但是OGNL表达式需要结合s标签来使用
(1) 直接显示一个值
(2)调用对象的方法或属性
(3)可以直接调用类里的静态方法, 把调用静态方法的开关打开
(4)计算某个表达式的值
<%@ 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>
<h1>演示ognl的几种用法</h1>
直接在页面上显示一个值:<s:property value="1"/><br>
调用对象里的方式:<s:property value="'hello'.toUpperCase()"/><br>
直接调用类里静态方法:<s:property value="@java.lang.Math@max(10,11)"/><br>
算术运算:<s:property value="1+2"/>
</body>
</html>
注意: 在调用静态方法时, 需要把静态方法调用的开关打开, 默认是关闭的
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
2. 值栈
什么是值栈: 值栈是struts2框架的数据中转站, 里面保存了当前Action对象和web对象引用(page, request, session, application, arrt, paramertes), 也可以手动保存自己的对象, 同时也可以随时将这些对象从值栈中取出来
值栈在哪: 每个请求都会产生一个值栈, 会放在request域中, 名字struts.valueStack
获取值栈的两种方式:
(1) 从request域中获取
(2) 通过ActionContext中的getValueStack方法获取
值栈包含两个逻辑部分: 对象栈和上下文栈
对象栈(List)存放: Action对象+其他对象
上下文栈(Map)存放: Action对象, web对象的引用, 其他对象
3. 值栈的存放数据
struts2框架会自动将当前Action的对象存放到对象栈中
3.1 如何向对象栈手动存放数据
对象栈是栈结构, 先进后出, 所有后方的元素在上边
(1) 匿名存放
(2) 有名字的存放, 实质上存放的是一个Map对象
@Override
public String execute() throws Exception {
ValueStack valueStack = ActionContext.getContext().getValueStack();
//匿名存放
valueStack.push("木木");
//有名存放
valueStack.set("username", "木木");
return SUCCESS;
}
3.2 如何向上下文栈里手动存放数据
@Override
public String execute() throws Exception {
ValueStack valueStack = ActionContext.getContext().getValueStack();
//向上下文栈存放数据
//valueStack.getContext().put("username", "木头");
ActionContext.getContext().put("username", "木木");
return SUCCESS;
}
4. 值栈的获取数据
注意: 获取值栈中的数据需要通过OGNL表达式结合s标签来获取,
4.1 如何获取对象栈里的数据
获取对象栈中的数据不需要加#
根据属性名取值: <s:property value="username"/>
根据序号取值: <s:property value="[0].top.username"/>
[0].top表示取对象栈里的第一个元素, 因为栈顶是一个map, 我们需要取出map里username这个key的值, 所以这么写[0].top.username
4.2 如何获取上下文栈里的数据
加#号来取上下文栈中的数据
例: <s:property value="#username"/>
5. 值栈的搜索顺序
(1). 如果不加#号, 先搜索对象栈, 再搜索上下文栈, 如果都搜索不到, 就不显示; 如果中途搜索到, 立即停止搜索
(2). 如果加#号, 直接搜索上下文栈, 如果搜索不到, 就不显示
把数据放到对象栈中有两种方法:
(1) 可以手动获取值栈, 手动把值存放进去
(2) 也可以直接在Action类中定义属性并提供get方法, 也能把数据放到对象栈中, 因为当前Action对象会自动保存到对象栈中, 那么里面的属性也在对象栈中
值栈的生命周期:
1.每一个请求都会产生一个值栈对象, 放在request的域中, 名字叫做struts.valueStack
2. 值栈的生命周期同request的生命周期
3. 值栈贯穿整个Action的生命周期
6. OGNL表达式对值栈的操作方法
6.1 #号的用法 : 从值栈的上下文栈中取值. 如果不加#, 就是优先从对象栈里取
加#号可以取pageContext,request,session,application,attr,parameters;
attr:依次寻找pageContext---->request---->session----->application
parameters:取请求中的参数值,取出的是一个数组,再通过[0]取出具体的值
取request域中的值:<s:property value="#request.username"/><br>
取session域中的值:<s:property value="#session.username"/><br>
取application域中的值:<s:property value="#application.username"/><br>
<!-- #attr.username 先从page域中寻找,再从request域中寻找,再从session域中,最后找application域 -->
取page域中的值:<s:property value="#attr.username"/><br>
取参数值:<s:property value="#parameters.username[0]"/><br>
#号还可以用来构造map集合和list集合
#的用法:构造集合
构造List集合,不要加#
<s:iterator value="{'汪峰','那英','周杰伦','哈林'}" var="star">
<s:property value="#star"/>
</s:iterator>
构造map集合:
<s:iterator value="#{'id':'1','username':'木之由'}" var="customer">
<s:property value="#customer.key"/>:<s:property value="#customer.value"/>
</s:iterator>
6.2 %号的用法
作用:
告诉执行环境, 把字符串当成OGNL表达式来解析
<s:textfield value="%{属性名}"></s:textfield>
告诉执行环境, 把一个OGNL表达式不要进行解析, 直接看成一个字符串
<s:property value="%{'木木'}"/>
6.3 $号的用法
作用: 用于在配置文件(struts.xml) 里取值栈里的值