Struts2之OGNL表达式与值栈对象及常用标签的使用
来源:互联网 发布:linux snmp 监控软件 编辑:程序博客网 时间:2024/05/16 08:58
一,概述
OGNL表达式
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目.Struts2使用OGNL作为默认的表达式语言.
OGNL优势
1)支持对象方法调用,如xxx.doSomeSpecial().
2)支持类静态的方法调用和值访问,表达式的格式:@[类全名(包括包路径)]@[方法名 | 值名],
例如:
@java.lang.String@format('foo %s', 'bar')
或@tutorial.MyConstant@APP_NAME
3)支持赋值操作和表达式串联,如price=100, discount=0.8,calculatePrice(),这个表达式会返回80.
4)访问OGNL上下文(OGNL context)和ActionContext;
5)操作集合对象.
总结
OGNL有一个上下文(OgnlContext)概念,其实它的上下文就是map结构,它实现了java.utils.Map接口.
public class OgnlContext extends Object implements Map{...}
二,OGNL的API类和方法
OgnlContext类(本质上是一个Map)
硬编码方式了解OgnlContext对象
1)Ognl表达式语言取值,取非根元素的值,必须用#号
/** * Ognl表达式语言取值,取非根元素的值,必须用#号 * @throws Exception */@Testpublic void testOgnl() throws Exception {OgnlContext context=new OgnlContext();User user=new User();user.setId(111);user.setName("张国荣");//存context.put("Leslie", "哥哥");//往非根元素放入数据,取值的时候要用#context.put("user", user);//拿数据:通过map//通过Ognl表达式取数据Object ognl = Ognl.parseExpression("#Leslie");//Object ognl = Ognl.parseExpression("#user.name");Object value = Ognl.getValue(ognl, context, context.getRoot());System.out.println(value);}
2)Ognl表达式语言取值,取根元素的值,不用#号
@Testpublic void testOgnl2() throws Exception {OgnlContext context=new OgnlContext();User user=new User();user.setId(111);user.setName("张国荣--哥哥");//往非根元素放入数据,取值的时候要用#context.setRoot(user);//往根元素中放入数据,取值时直接用属性即可//拿数据:通过map//先构建一个ognl表达式,再解析表达式,通过Ognl表达式取数据Object ognl = Ognl.parseExpression("name");Object value = Ognl.getValue(ognl, context, context.getRoot());System.out.println(value);}
3)Ognl对静态方法调用的支持
@Testpublic void testOgnl3() throws Exception {OgnlContext context=new OgnlContext();//Object ognl = Ognl.parseExpression("@Math@floor(11.5)");//由于Math类比较常用,设计的比较特殊,所以可以这样写Object ognl = Ognl.parseExpression("@@floor(18.5)");Object value = Ognl.getValue(ognl, context, context.getRoot());System.out.println(value);}
三,ValueStack对象
1) ValueStack实际是一个接口,在Struts2中使用OGNL时,实际上使用的是实现了该接口的OgnlValueStack类,这个类是Struts2使用OGNL的基础.
public interface ValueStack {...}2)ValueStack特点:ValueStack贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前Action 对象和其他相关对象.Struts2框架把 ValueStack 对象保存在名为 “struts.valueStack” 的request请求属性中,传入到jsp页面.
3)开发者只需要通过ActionContext对象就可以访问struts的其他的关键对象.(ActionContext是给开发者用的,便于学习与使用)
4) ObjectStack: Struts 把动作和相关对象压入 ObjectStack 中--List
ContextMap: Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 ContextMap 中
Struts 会把下面这些映射压入 ContextMap 中
parameters: 该 Map 中包含当前请求的请求参数
request: 该 Map 中包含当前 request 对象中的所有属性
session: 该 Map 中包含当前 session 对象中的所有属性
application:该 Map 中包含当前 application 对象中的所有属性
attr: 该 Map 按如下顺序来检索某个属性: request, session, application
ValueStack数据:
root=CompoundRoot表示的根元素数据,里面存放当前Action对象,成员变量(要提供相应的setter与getter方法才能通过<s:debug></s:debug>标签看到成员变量信息)等等.
context=OgnlContext主要就是存储一些域数据.
5)获取值栈ValueStack的两种方式,在同一个Action中不同方式拿到的值栈对象是相同的.
private void vs() throws Exception {//获取值栈对象:方式一HttpServletRequest request = ServletActionContext.getRequest();ValueStack vs1 = (ValueStack) request.getAttribute("struts.valueStack");//获得值栈对象:方式二ActionContext ac = ActionContext.getContext();ValueStack vs2 = ac.getValueStack();System.out.println(vs1 == vs2);//輸出:true}}
四,struts标签(使用了OGNL表达式语言)
1)存数据
package cn.bighuan.b_ognl;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.util.ValueStack;/** * struts的数据流转 * @author bighuan * */public class OgnlAction extends ActionSupport{//Action全局成员都是根元素的值private User user=new User(11,"Leslie");public void setUser(User user) {this.user = user;}public User getUser() {return user;}@Overridepublic String execute() throws Exception {ActionContext ac = ActionContext.getContext();//这两种存数据的方式有点不一样Map<String, Object> request = ac.getContextMap();request.put("request_data","request_data");Map<String ,Object> request1 = (Map<String, Object>) ac.get("request");request1.put("request_data111","request_data111");Map<String, Object> session = ac.getSession();Map<String, Object> application = ac.getApplication();request.put("request_data","request_data");session.put("session_data", "session_data");application.put("application_data", "application_data");ValueStack vs = ac.getValueStack();System.out.println(vs);return SUCCESS;}2)jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>My JSP 'index.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> <%--页面必须要拿到ValueStack --%> <h3>取根元素的值 </h3> <s:property value="user.name"/><br/> <s:property value="user.id"/><br/> <hr/> <h3>取非根元素的值 </h3> <s:property value="#request.request_data"/><br/> <s:property value="#session.session_data"/><br/> <s:property value="#application.application_data"/><br/> <%--自动找request-->session-->application --%> <h5>取非根元素的值 :通过attr取数据 </h5> <s:property value="#attr.request_data"/><br/> <s:property value="#attr.session_data"/><br/> <s:property value="#attr.application_data"/><br/> <hr/> <h3>直接通过key取值 </h3> ********Map<String, Object> request = ac.getContextMap();两种方式取值******************<br/> <s:property value="#request_data"/><br/> <s:property value="#request.request_data"/><br/> ***Map<String ,Object> request1 = (Map<String, Object>) ac.get("request");只有一种方式****<br/> <%-- <s:property value="#request_data111"/><br/>错误 --%> <s:property value="#request.request_data111"/><br/> <s:property value="user.name"/><br/><br/> <br/>*******************重要点********************** <hr>通过get("request")得到map对象得到的数据,这种方式只能通过#+域+key取值</hr><br/> <s:property value="#request.request_data111"/> <%--调试标签 --%> <s:debug></s:debug> </body></html>3_存List数据或Map数据
package cn.bighuan.b_ognl;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.util.ValueStack;public class OgnlDemo3 extends ActionSupport{@Overridepublic String execute() throws Exception {//迭代标签List<User> list = new ArrayList<User>();Map<Integer,User> map = new HashMap<Integer, User>();// 初始化for (int i=0; i<10; i++) {User user = new User(i,"Leslie" + i);list.add(user);map.put(user.getId(), user);}// 保存 ActionContext.getContext().getContextMap().put("list", list);ActionContext.getContext().getContextMap().put("map", map);return super.execute();}}
4)迭代器标签
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>My JSP 'ognl_tag.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"><style type="text/css" > .odd{ background-color: red; } .even{ background-color:blue;} </style></head><body><br />一、. list迭代</br><table border="1"><tr><td>编号</td><td>名称</td></tr><s:iterator var="user" value="#request.list" status="st"><tr class=<s:property value="#st.even?'even':'odd'"/>><td><s:property value="#user.id" /></td><td><s:property value="#user.name" /></td></tr></s:iterator></table><br />二、迭代map</br><table border="1"><tr><td>编号</td><td>名称</td></tr><s:iterator var="en" value="#request.map" status="st"><tr><td><s:property value="#en.key" /></td><td><s:property value="#en.value.name" /></td></tr></s:iterator></table><!-- Ognl表达式可以取值,也可以动态构建集合 --></body></html>
五,ValueStack总结
1)值栈以struts.valueStack的名字存储在request请求中,值栈主要包含两个栈:对象栈和Map栈.
对象栈存储的是用户的基本数据和对象数据 ; Map栈主要存储的是域对象属性。
用户每次一个请求就一个Action实例,对应一个值栈对象。
2)思考:
放在request中的值栈中可以存储session和servletContext域数据,显然request的作用有没有那么大?直接使用拷贝的方式以key=value的方式拷贝到Map栈对应的Map中.
Map栈中的_root
debug可见该属性中引用的是对象栈数据。如果在Map栈中不存储_root对于对象栈的引用,那么开发者需要访问数据时候首先要区分是访问对象栈还是Map栈,比较繁琐。因此以后操作数据直接操作Map栈即可。
- Struts2之OGNL表达式与值栈对象及常用标签的使用
- struts2标签及ognl表达式
- ognl表达式与struts2标签
- ognl学习(二)---struts2标签库与OGNL表达式的使用
- Struts2标签、Ognl表达式、el表达式、jstl标签库这四者之间的关系与各自使用
- Struts2使用之值栈与OGNL
- Struts2学习之3(文件的上传下载,OGNL表达式,常用标签,表单重复提交)
- Struts2 OGNL与标签使用
- struts2 之ognl表达式与值栈(03)
- Struts2 OGNL表达式的iterator标签使用详解
- Struts中的OGNL表达式语言1/Struts标签与OGNL表达式语言实例演练2/Struts2常用标签总结3
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- 从MySQL数据库中导出数据
- datastage序列job参数传入内部嵌套的job注意事项
- 如何解决web系统session劫持
- CSS的规范化
- 2017年华东师范大学网络赛 C
- Struts2之OGNL表达式与值栈对象及常用标签的使用
- View的绘制流程源码分析(Android开发艺术探索学习笔记)
- 单位阶跃函数(Heaviside/unit step function)—— 化简分段函数
- 引导页的实现
- 函数
- js中的Math和Date对象
- Ganglia与Nagios介绍
- Fedora 安装ruby
- 市场细分时代,PC应如何利用好用户思维?