1. OGNL

1.1 OGNL概述

1.1 什么是OGNL

  • OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
  • OGNL:对象导航语言,可以方便地操作对象属性的开源表达式语言,使页面更简洁;比EL表达式强大很多倍。可以调用Struts2的值栈的数据。OGNL其实第三方的表达式语言。
  • EL:从域对象中获取数据,或者从EL的11个对象中获取。

1.1.2 OGNL的优势

  • Struts 2默认的表达式语言是OGNL,原因是它相对其它表达式语言具有下面几大优势:

    • 支持对象方法调用,如xxx.doSomeSpecial();

    • 支持类静态的方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 | 值名],例如:@java.lang.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME;

    • 支持赋值操作和表达式串联,如price=100, discount=0.8, calculatePrice(price*discount),这个表达式会返回80;

    • 访问OGNL上下文(OGNL context)和ActionContext

    • 操作集合对象。

    • 可以直接new一个对象

1.1.2 OGNL使用的要素

  • 表达式
  • 根对象
  • Context对象

1.2 OGNL的Java环境入门【了解】

1.2.1 访问对象的方法

@Test	// OGNL调用对象的方法
public void test1() throws OgnlException {
// 获得context
OgnlContext context = new OgnlContext();
// 获得根对象
Object root = context.getRoot();
// 执行表达式
Object object = Ognl.getValue("'helloworld'.length()", context, root);
System.out.println(object);//10
}

1.2.2 访问对象的静态方法

@Test	// OGNL访问对象的静态方法
public void test2() throws OgnlException {
// 获得context
OgnlContext context = new OgnlContext();
// 获得根对象
Object root = context.getRoot();
// 执行表达式@类名@方法名
Object object = Ognl.getValue("@java.lang.Math@random()", context, root);
System.out.println(object);// 0-1的随机数
}

1.2.3 获得Root中的数据

@Test	// 访问Root中的数据,不需要加#
public void test3() throws OgnlException {
// 获得context
OgnlContext context = new OgnlContext();
// 执行表达式
User user = new User("aaa", "123");
context.setRoot(user);
// 获得根对象
Object root = context.getRoot();
Object username = Ognl.getValue("username", context,root);
Object password = Ognl.getValue("password", context,root);
System.out.println(username+" "+password);
}

1.2.4 获得OgnlContext中的数据

@Test	// 访问Context中的数据,需要加#
public void test4() throws OgnlException {
// 获得context
OgnlContext context = new OgnlContext();
// 获得根对象
Object root = context.getRoot();
// 向context中存入数据
context.put("name", "张三");
// 执行表达式
Object object = Ognl.getValue("#name", context, root);
System.out.println(object);
}

1.3 OGNL的Struts2的环境入门

1.3.1 访问对象的方法

  • 在web.xml文件中配置核心过滤器
<!-- 配置核心过滤器 -->
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
  • 引入struts核心配置文件
  • 编写一个JSP../WebContent/demo1/test.jsp,引入struts的标签库
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>OGNL在Struts2环境中的入门</h1>
<h3>调用对象的方法</h3>
<s:property value="'struts'.length()"/>
</body>
</html>

1.3.2 访问对象的静态方法

  • 静态方法访问在Struts2中默认是关闭的,需要手动开启一个常量
  • 在配置文件中开启常量
<struts>
<!-- 开启静态方法 -->
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
</struts>
  • JSP
<h1>OGNL在Struts2环境中的入门</h1>
<h3>调用对象的方法</h3>
<s:property value="'struts'.length()"/> <h3>调用对象的静态方法</h3>
<!-- 静态方法访问在Struts2中默认是关闭的,需要手动开启一个常量 -->
<s:property value="@java.lang.Math@random()"/>
  • 测试:访问jsp页面,能正常显示struts的长度和产生的随机数

2. 值栈

2. 1什么是值栈

  • 值栈ValueStack是Struts的一个接口。OgnlValueStack是ValueStack的实现类,客户端发送一个请求struts2架构会创建一个action实例同时创建一个OgnlValueStack值栈实例,OgnlValueStack贯穿整个Action生命周期,struts2中使用OGNL将请求Action的参数封装为对象存储到值栈中,并通过OGNL表达式读取值栈中的对象属性值。
  • 值栈其实类似于一个数据中转站,Struts2中的数据都保存到了值栈中。
  • request域中的数据只能在jsp页面中取出,但是值栈中的数据可以在jsp页面、Action、配置文件中取出。

2.2 值栈的内部结构

  • ValueStack中有两个主要的区域:

    • root区域:其实就是一个ArrayList。里面一般放置对象。获取root数据需要加#。
    • context区域:其实就是一个Map。放置的是web开发的常用对象数据的引用。获取context数据需要加#。
      • request
      • session
      • application
      • attr
  • 所说的操作值栈,通常指的是操作ValueStack中的root区域。

2.3 值栈与ActionContext的关系

  • ActionContext:Action的上下文
  • 通过源码可以看到。当前请求过来的时候,执行过滤器中doFilter方法,在这个方法中创建ActionContext,在创建ActionContext过程中,也创建了ValueStack对象,并且将ValueStack对象传递给ActionContext对象。所以可以通过ActionContext获取值栈对象。
  • ActionContext对象之所以能够访问Servlet的API(访问的是域对象的数据)是由于其内部有值栈的引用。

2.4 获得值栈

package com.itzhouq.struts.valueStack;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack; /**
* 获得值栈的方式
* @author itzhouq
*
*/
public class ValueStackDemo1 extends ActionSupport {
@Override
public String execute() throws Exception {
// 方式一:
ValueStack valueStack1 = ActionContext.getContext().getValueStack(); // 方式二:
ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack"); // 一个Action的实例,只会创建一个ValueStack的对象
System.out.println(valueStack1 == valueStack2);//true
return NONE;
}
}

2.5 操作值栈

  • 操作值栈----向值栈中存储数据

2.5.1 方式一:在Action中提供属性的get方法的方式

  • 默认情况下,将Action对象压入到值栈。Action的属性也会在值栈中。

  • 编写Action类ValueStackDemo2

    package com.itzhouq.struts.valueStack;
    
    import com.itzhouq.struts.domain.User;
    import com.opensymphony.xwork2.ActionSupport; /**
    * 操作ValueStack,方式一:利用Action本身在值栈中的特性
    * @author itzhouq
    *
    */
    public class ValueStackDemo2 extends ActionSupport {
    private User user; public User getUser() {
    return user;
    }
    @Override
    public String execute() throws Exception {
    // 向ValueStack中存储数据
    user = new User("李斌","456");
    return SUCCESS;
    }
    }
  • 在配置文件中配置

    action name="valueStackDemo2" class="com.itzhouq.struts.valueStack.ValueStackDemo2">
    <result>/demo1/success.jsp</result>
    </action>
  • 跳转页面success.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib uri="/struts-tags" prefix="s"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h1>查看值栈的内部结构</h1>
    <s:debug></s:debug>
    <!-- 方式一的获取:利用Action在值栈中的特性 -->
    <s:property value="user.username"/>
    <s:property value="user.password"/> </body>
    </html>
  • 访问http://localhost/Struts2_day03/valueStackDemo2.action

2.5.2 使用ValueStack中本身的方法的方式

  • 编写Action类ValueStackDemo3

    package com.itzhouq.struts.valueStack;
    
    import com.itzhouq.struts.domain.User;
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.util.ValueStack; /**
    * 操作值栈:方式二:调用值栈中的方法实现
    * @author itzhouq
    *
    */
    public class ValueStackDemo3 extends ActionSupport{
    @Override
    public String execute() throws Exception {
    // 向值栈中保存数据:
    // 获得值栈对象
    ValueStack valueStack = ActionContext.getContext().getValueStack();
    // 使用push(Object obj); set(String key, Object obj);
    User user = new User("李世民","26");
    // 现在user在栈顶的位置
    valueStack.push(user);
    valueStack.set("name", "赵子龙");// 创建一个Map集合,将Map压入到栈中
    return super.execute();
    }
    }
  • 在配置文件中配置,跳转页面success.jsp

    <h1>操作值栈</h1>
    <s:debug></s:debug>
    <!-- 方式一的获取:利用Action在值栈中的特性 -->
    <%-- <s:property value="user.username"/>
    <s:property value="user.password"/> --%> <!-- 方式二的获取:调用valueStack的本身的方法 -->
    <s:property value="username"/>
    <s:property value="password"/> <s:property value="name"/>
  • 访问http://localhost/Struts2_day03/valueStackDemo3.action

2.6 获得值栈数据

  • 获取值栈中的数据就是在页面中使用OGNL表达式

    • 获取root的数据,不需要加#
    • 获取context中的数据,需要加#
  • 编写Action了ValueStackDemo4

    package com.itzhouq.struts.valueStack;
    
    import java.util.ArrayList;
    import java.util.List; import org.apache.struts2.ServletActionContext; import com.itzhouq.struts.domain.User;
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionSupport; /**
    * 获取值栈的数据
    * @author itzhouq
    *
    */
    public class ValueStackDemo4 extends ActionSupport{
    @Override
    public String execute() throws Exception {
    // 向值栈中保存一个对象
    User user = new User("aaa", "111");
    ActionContext.getContext().getValueStack().push(user); // 向值栈中保存一个集合
    List<User> list = new ArrayList<User>();
    list.add(new User("aaa","111111"));
    list.add(new User("bbb","222222"));
    list.add(new User("ccc","333333"));
    ActionContext.getContext().getValueStack().set("list", list); // 向context中存入数据
    ServletActionContext.getRequest().setAttribute("name", "r李斌");
    ServletActionContext.getRequest().getSession().setAttribute("name", "s赵红");
    ServletActionContext.getServletContext().setAttribute("name", "a邓子龙"); return super.execute();
    }
    }
  • 在主配置文件中配置Demo4,编写跳转页面success2.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib uri="/struts-tags" prefix="s"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h1>获取值栈的数据</h1>
    <s:debug></s:debug>
    <!--获取一个对象的数据 -->
    <s:property value="username"/>
    <s:property value="password"/>
    <br><br> <!-- 获取集合中数据 -->
    <s:property value="list[0].username"/>
    <s:property value="list[0].password"/><br>
    <s:property value="list[1].username"/>
    <s:property value="list[1].password"/><br>
    <s:property value="list[2].username"/>
    <s:property value="list[2].password"/><br> <br><br>
    <!-- 获取context中的数据 -->
    <s:property value="#request.name"/><br>
    <s:property value="#session.name"/><br>
    <s:property value="#application.name"/><br>
    </body>
    </html>
  • 测试:访问http://localhost/Struts2_day03/valueStackDemo4.action

2.7 EL为何能访问值栈的数据

  • 因为Struts2的框架的底层对request.getAttribute(String name);进行了增强。

3. OGNL中的特殊字符

3.1 #号

3.1.1 获取context的数据

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>#的用法</h1>
<%
request.setAttribute("name", "李斌");
%>
<s:property value="#request.name"/>
<hr> </body>
</html>
  • 在页面能获取到request中存储的数据

3.1.2 使用#号构建Listmap集合

  • ../WebContent/demo2/test.jsp
<h3>构建list集合</h3>
<s:iterator var="i" value="{'aa','bb','cc'}">
<s:property value="i"/> -- <s:property value="#i"/> <br>
</s:iterator> <h3>构建Map集合1</h3>
<s:iterator value="#{'aa':'11111', 'bb':'22222', 'cc':'33333' }">
<s:property value="key"/>--<s:property value="value"/><br>
</s:iterator> <h3>构建Map集合2</h3>
<s:iterator var="entry" value="#{'aa':'11111', 'bb':'22222', 'cc':'33333' }">
<s:property value="#entry.key"/>--<s:property value="#entry.value"/><br>
</s:iterator> <h3>实例1</h3>
<s:radio list="{'男', '女' }" name="sex1" label="性别"/><br>
<h3>实例2</h3>
<s:radio list="#{'1':'男','2': '女' }" name="sex2" label="性别"/>
  • 访问http://localhost/Struts2_day03/demo2/test.jsp

3.2 %号

  • 强制解析成OGNL表达式

  • ../WebContent/demo2/test2.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib uri="/struts-tags" prefix="s"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h3>%的使用</h3>
    <%
    request.setAttribute("name", "罩子龙");
    %>
    姓名:<s:textfield name="name" value="%{#request.name}"/>
    </body>
    </html>

3.3 $号

  • 在配置文件中使用$

Struts框架笔记03_OGNL表达式与值栈的更多相关文章

  1. struts框架问题六之从值栈中获取值

    6. 问题六: 在JSP中获取值栈的数据 * 总结几个小问题: > 访问root中数据 不需要# > 访问context其它对象数据 加 # > 如果向root中存入对象的话,优先使 ...

  2. struts框架问题五之向值栈中保存数据

    5. 问题五: 向值栈保存数据 (主要针对root栈) > valueStack.push(Object obj); * push方法的底层调用root对象的push方法(把元素添加到0位置) ...

  3. Struts2之 OGNL表达式和值栈

    技术分析之OGNL表达式概述(了解)        1. OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写        * 所谓对象图,即以任意 ...

  4. EL表达式获取值栈数据

    ---------------------siwuxie095 EL 表达式获取值栈数据 1.导入 JSTL 相关包,下载链接: (1)http://tomcat.apache.org/taglibs ...

  5. Struts2-从值栈中获取数据-EL表达式从值栈获取

    从值栈获取数据 1 使用struts2的标签+ognl表达式获取值栈数据 (1)<s:property value=”ognl表达式”/> 获取字符串

  6. Struts2_day03--从值栈获取数据_EL表达式获取值栈数据(为什么)

    从值栈获取数据 1 使用struts2的标签+ognl表达式获取值栈数据 (1)<s:property value=”ognl表达式”/> 获取字符串 1 向值栈放字符串 2 在jsp使用 ...

  7. struts框架中OGNL表达式的使用之jsp页面获取action中的属性值

    在jsp页面中获取action中的值: 1.写一个action类OgnlAction类: 需要注意的地方: 如果在aciton中直接使用ognl表达式,将值存储的值栈中,是不能通过跳转将值传到jsp页 ...

  8. Struts工作机制图+OGNL+EL+值栈(Map,对象栈)

    struts 值栈  通过get set方法 方便的获取,设置属性值      比如从jsp页面传来的參数...从Action设置jsp所要回显的内容 注意EL表达式,struts2对request进 ...

  9. struts2(四) ognl表达式、值栈、actionContext之间的关系

    今天来说说ognl表达式在struts2中的运用. --wh 一.什么是Ognl? 通过百度百科查询到的解释,其中详细的说明了OGNL的作用. 下面我们就对OGNL这5个作用进行讲解 1.存取对象的任 ...

随机推荐

  1. Jmeter里http接口的执行顺序是顺序执行

    1,如果在一个线程组里则是顺序执行 2,如果不在一个线程组里,就勾选独立运行各个线程组,在一个运行结束后启动下一个线程组

  2. matlab学习笔记4--多媒体文件的保存和读取

    一起来学matlab-matlab学习笔记4 数据导入和导出_2 多媒体文件的保存和读取 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用&g ...

  3. CentOS7 安装特定版本的Docker

    先卸载旧版本   sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-late ...

  4. JVM 线上故障排查基本操作--内容问题排查

    内存问题排查 说完了 CPU 的问题排查,再说说内存的排查,通常,内存的问题就是 GC 的问题,因为 Java 的内存由 GC 管理.有2种情况,一种是内存溢出了,一种是内存没有溢出,但 GC 不健康 ...

  5. iOS - 点击按钮实现简单的复制功能

    UIPasteboard使用 基本使用: - (void)copyClick { UIPasteboard *pab = [UIPasteboard generalPasteboard]; pab.s ...

  6. [LeetCode] 399. Evaluate Division 求除法表达式的值

    Equations are given in the format A / B = k, where A and B are variables represented as strings, and ...

  7. [LeetCode] 461. Hamming Distance 汉明距离

    The Hamming distance between two integers is the number of positions at which the corresponding bits ...

  8. SpringMVC的拦截器讲解

    Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理. 用户可以自己定义一些拦截器来实现特定的功能. 谈到拦截器,还要向大家提一个词 ...

  9. hashMap常见问题

    [解析hashMap的源码实现]      点击进入hashMap的源码实现 0.谈谈对hashMap的理解? 从底层结构.存取.扩容.冲突.实现原理.源码等方面说明. 1.你知道哪些常用的Map集合 ...

  10. 【剑指offer】面试题 24. 反转链表

    面试题 24. 反转链表