大致内容

    ognl概述
    ognl入门
    值栈

一、OGNL概述

  OGNL,全称为Object-Graph Navigation Language,对象图导航语言
      它是一个功能强大的表达式语言,用来获取和设置Java对象的属性,
      它旨在提供一个更高的更抽象的层次来对Java对象图进行导航。 

  struts2自带的表达式语言就是OGNL
    >支持对象方法调用
    >支持类静态方法调用和值访问
    >【主要用法】在struts2中操作值栈
    和struts2标签一起使用来操作值栈

  OGNL不是struts2的一部分,是一个单独的项目,可以独立使用,但常用于struts2中操作值栈
  同样,和JSTL标签库一样先要导入jar包,但struts2里已经带有(myeclispe中JSTL也自带了)
  使用struts2标签库的时候也要引入标签库

二、OGNL入门案例  

  OGNL入门案例:
    导入标签库
      <%@ taglib uri="/struts-tags" prefix="s" %>
    使用的方式
      <!-- 里面的 value 值即为ognl表达式,此标签主要用于操作值栈 -->
      <s:property value="'hello'.length()"/>

<%@ 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 'ognl.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>
<!-- 里面的 value 值即为ognl表达式,例如用法1:对象方法的调用 -->
<s:property value="'hello'.length()"/>
</body>
</html>

三、值栈  

  1.概述:
    web阶段,都是servlet中进行操作,把数据放域对象,再使用EL表达式
    在页面显示
    在struts2中提供了一种存储的机制,就类似于域对象,就称之为值栈
    可以存取数据
    在action中可以放数据在值栈,再通过页面取到(当然,就用域对象也是可以,但不学值栈不能说学了struts2)

  servlet和action的区别:
    servlet:在第一次访问时创建,只创建一次 ===单实例对象
    action:也是在访问时创建,但每次访问action时都会创建action对象 ===多实例对象
    (验证方法,在构造函数中输出内容,若每次访问都有输出,则证明执行了构造函数,创建了对象)

    每次访问action时都会创建acion的对象,在每个acion对象中都会有一个值栈对象
  而且是有且只有一个值栈对象,由此可知,值栈生命周期是一次请求!

  2.值栈的内部结构  

  值栈的内部结构:
    两部分:
      root 【经常操作的是这个】(本身是list集合 继承了ArrayList) 根对象
      context本身是map集合,实现了Map)存的是对象的引用(request,session,application,parameters,attr五个对象的引用)
        (值栈可以通过查看 variable查看到)

  .如何获取值栈对象:(两种方式,掌握较常用的方式)

    1.【常用】使用ActionContext类(静态方法获得本类实例)来获取(getValueStack())

ActionContext context = ActionContext.getContext(); 

  4.向值栈中放数据:
    <s:debug/> (调试用的,直接给用户用用户直接疯掉...)
    配置页面和action (见stack.jsp)
    页面会出现超链接
    用户点开会疯的 ,一大堆的。。。
    例子里值栈里栈顶是action ,是action的引用
  放数据:
    有多种方式,但常用的是一两种
      获取值栈对象,调用它的set()方法 ===使用ActionContext()方法
      获取值栈对象,调用它的push()方法
      【常用】 在acion定义一个成员变量,然后生成变量的get()方法,在方法使用时再设置值也能放到值栈中去
        第三种方式直接放在action里面,而前两种需要单独开辟空间
        (三种方法均在valuestack.java中进行演示)

package cn.action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack; public class StackAction extends ActionSupport { //定义私有成员变量
private String username;
//定义get()方法
public String getUsername() {
return username;
} @Override
public String execute() throws Exception {
//在使用时设置值
username = "江北01";//===方式3
ActionContext context = ActionContext.getContext();
ValueStack stack = context.getValueStack();
stack.push("10086");//===方式2
stack.set("name", "value");//===方式1
return "success";
}
}

        更多的是向值栈中放对象,放list集合等:
    1.在成员变量出定义一个对象,并且生成其get()方法,再在方法里对对象赋值
      基本流程都非常相似,见ObjectStackAction

    2.放list集合(作表单回显等操作)

package cn.action;

import java.util.ArrayList;
import java.util.List; import com.opensymphony.xwork2.ActionSupport; import cn.entity.User; public class GetStackAction extends ActionSupport { private String username; public String getUsername() {
return username;
} //定义成员变量,此处执行new构造操作,不执行下面也得执行
// private User user = new User();
     //不要new来浪费空间,后面返回的直接赋给它即可!
    private List<User> list
//生成get方法 public User getUser() { return user; } //定义list集合 private List<User> list = new ArrayList<User>();
//定义get方法 public List<User> getList() { return list; } @Override public String execute() throws Exception { //值栈中放字符串 username = "江北01"; //值栈中放对象 user.setUsername("jiangbei01"); user.setPassword("123"); User user1 = new User(); user1.setUsername("小王"); user1.setPassword("123"); User user2 = new User(); user2.setUsername("小李"); user2.setPassword("123"); //值栈中放集合  list.add(user1); list.add(user2); return "success"; } }

  5.从值栈中取数据(day02已经有相关的一些使用方法):
    (取的都是方式3放的数据)
  使用struts2的标签和ognl使用来取值栈的值
    <s:propertiry value="ognl表达式"/>
  获取字符串:
    <!-- 根据名称可以得到值栈的值,它会去找get()方法去拿值 -->
    <s:property value="username"/>
  获取对象:
    <!-- 获取值栈中对象的值 -->
  第一步先去找user的get方法,返回user对象,再通过User的get/set()方法找到值
    <s:property value="user.username"/>
    <s:property value="user.password"/>
  获取集合:
    1.【内容少的时候用,较少用】写法太固定,不灵活
      <!-- 获取值栈中list集合的值 -->
      <s:property value="list[0].username"/>
      <s:property value="list[1].password"/>
    2. <s:iterator value="list">
      <!-- 可以直接写list里面的User对象的属性值,会自动迭代查找 -->
      <s:property value="username"/>
      </s:iterator>
      对比之前的EL的 item 和var 会觉得少了点什么,引出第三种
      注意:<!-- -->标签不能注释<>标签,应当使用JSP的注释:<%-- --%>
    3.【常用】
      <s:iterator value="list" var="user">
      <!-- 表示取得是context中的临时值 -->
      <s:property value="#user.username"/>
      <s:property value="#user.password"/>
      </s:iterator>
  使用这种方式后,每次遍历List集合后遍历的元素会放到context中,也就是context中会临时存放,
  context中是map结构
  key存的就是var的值,value存的就是user对象的引用

  获取context中的数据,需要使用# ,它才知道取得是context中的内容
  这样设计是为了提高取值效率

  如果要在上述Iterator之间取值,由于不能使用EL表达式,可以直接将整个标签复制过来
  例如<a href="${pageContext.request.contextPath}/cus_list?psd=<s:property value="#user.password"/>"></a>

各种取数据的方式演示如下:

<%@ 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 'stack.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>
<!-- struts2查看值栈标签 -->
<s:debug></s:debug> <br>
<!-- 根据名称可以得到值栈的值,它会去找get()方法去拿值 -->
<s:property value="username"/>
<!-- 获取值栈中对象的值,先找user的get方法返回user,再通过user的get/set方法找值 -->
<s:property value="user.username"/>
<s:property value="user.password"/>
<!-- 获取值栈中list集合的值 的第一种方式,不灵活-->
<s:property value="list[0].username"/>
<s:property value="list[1].password"/>
<!-- 获取集合第二种标签,类似JSTL的forEach value会去找getList()方法得到list-->
<s:iterator value="list">
<!-- 可以直接写list里面的User对象的属性值,会自动迭代查找 -->
<s:property value="username"/>
</s:iterator>
<%--获取List的第三种方式,注意这是JSP注释,也是使用iterator --%>
<s:iterator value="list" var="user">
<!-- 表示取得是context中的临时值 -->
<s:property value="#user.username"/>
<s:property value="#user.password"/>
</s:iterator>
<s:textarea name="username" value="%{#request.req}"></s:textarea>
</body>
</html> 

  如何获取set/push()方法放的值栈数据(会用)
    set中是set(name,value)的形式:用前面的用到的标签,value出填set()方法中的name值即可
      <s:property value="itcast"/>
    push中是直接放入object的,不能根据名称取到,利用set或push方法放的元素会放在一个叫 top的数组中
      可以通过 top 数组取到,但写法特别怪:
      [0].top 取到栈顶值

  扩展延伸: 

  *其实上面的通过OGNL表达式取到的值,直接写EL表达式与JSTL也是可以实现的
  这里有必要讲的是里面的简单原理,即为什么能取到呢
    <c:forEach items="${list}" var="user">
      ${user.username}
    </c:forEach>

  EL操作域对象里面的值,都是通过setAttribute() getAttribute()方法存取域对象里的值
  底层是增强了request里的getAttribute()方法
    1.若域对象中有,则从域对象中取
    2.若域对象中没有,则从值栈中取出来,再放入域对象中
  过滤器那个doFilter()方法中,有个wrapRequest()方法 request = wrapRequest(request);
  通过继承HttpServletRequestWrapper类来增强,增强的方法就叫做getAttribute()方法

  所以,EL表达式本身取得还是域对象的值!但是不建议使用EL来去值栈的数据,会影响性能

  OGNL中两个符号的使用:
    #
      使用#来获取context中的数据,访问非根元素对象。实际上,#相当于ActionContext.getContext()
      比如context中存放了request ,可以实现向request域中放值
      ServletActionContext 可以获取,相当于servletContext的一顶九
      #context里Key的名称.xx 用的较少,要取域对象,可以使用EL使用
    %
      在struts2的标签中,有一类标签叫表单标签
      在struts2的标签中不能直接识别OGNL,需要在%之后
      例如这里它识别不了
        <s:textarea name="username" value="#request.req"></s:textarea>
      需要使用%{}
        <s:textarea name="username" value="%{#request.req}"></s:textarea>

更多表单标签会在第四天引入,但实际使用不多,性能等方面不行

struts2第三天——值栈的更多相关文章

  1. struts框架值栈问题三之值栈的创建和ActionContext对象的关系

    3. 问题三 : 值栈对象的创建,ValueStack 和 ActionContext 是什么关系? * 值栈对象是请求时创建的 * ActionContext是绑定到当前的线程上(一个Action访 ...

  2. Struts2基础学习(七)—值栈和OGNL

    目录: 一.值栈 二.OGNL表达式 一.值栈(ValueStack) 1.定义      ValueStack贯穿整个Acton的生命周期,每个Action类的对象实例都拥有一个ValueStack ...

  3. 走进Struts2(五)— 值栈和OGNL

    值栈 1.值栈是什么? 简单说:就是相应每个请求对象的轻量级的内存数据中心. Struts2引入值栈最大的优点就是:在大多数情况下,用户根本无须关心值栈,无论它在哪里,不用管它里面有什么,仅仅须要去获 ...

  4. struts2 ognl表达式访问值栈

    1:简单的说,值栈是对应每一个请求对象的轻量级的数据存储中心,在这里统一管理着数据,供Action.Result.Interceptor等Struts2的其他部分使用,这样数据被集中管理起来而不凌乱. ...

  5. Struts2知识点小结(三)--值栈与ognl表达式

    1.问题一 : 什么是值栈 ValueStack        回顾web阶段 数据交互问题?        客户端提交数据  到  服务器端    request接受数据+BeanUtils实体封装 ...

  6. Struts2之 OGNL表达式和值栈

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

  7. 【基于初学者的SSH】struts2 值栈的详解与struts2标签库+ognl表达式

    一:什么是值栈:struts2里面本身提供的一种存储机制,类似于域对象,值栈,可以存值和取值 特点:先进后出,最上面的元素叫做栈顶,也叫压栈. <s:debug></s:debug& ...

  8. struts2 值栈分析

    目录 一.值栈分为两个逻辑部分 二.Struts2 利用 s:property 标签和 OGNL表达式来读取值栈中的属性值 1.值栈中的属性值: 2.读取对象栈中对象的属性: 3.默认情况下,Acti ...

  9. [原创]java WEB学习笔记59:Struts2学习之路---OGNL,值栈,读取对象栈中的对象的属性,读取 Context Map 里的对象的属性,调用字段和方法,数组,list,map

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

随机推荐

  1. Python 中单双引号

    TODO, 在python中, 其实单双引号还是有分别的, 具体是什么?

  2. 3.Spring MVC return url问题总结

    一.return "cartSuccess" 和 return "redirect:/cart/cart.html" 的区别 二.return modelAnd ...

  3. BeautifulSoup爬虫基础知识

    安装beautiful soup模块 Windows: pip install beautifulsoup4 Linux: apt-get install python-bs4 BS4解析器比较 BS ...

  4. Oracle EBS 系统仅存在英文的环境

    系统管理员 应用服务器 adadmin 编译

  5. [C# | XML] XML 反序列化解析错误:<xml xmlns=''> was not expected. 附通用XML到类解析方法

    使用 XML 反化时出现错误: public static TResult GetObjectFromXml<TResult>(string xmlString) { TResult re ...

  6. 纲举目张:打通MySQL架构和业务的任督二脉

    目前,在很多OLTP场景中,MySQL数据库都有着广泛的应用,也有很多不同的使用方式.从数据库的业务需求.架构设计.运营维护.再到扩容迁移,不同的MySQL架构有不同的特点,适应一定的业务场景,或者解 ...

  7. mysqlbinlog usage

    [root@localhost mysql3306]# mysqlbinlogmysqlbinlog Ver 3.4 for el7 at x86_64Copyright (c) 2000, 2018 ...

  8. css3实现border渐变色

    案例1 .box{ width: 100px; height: 100px; border:10px solid #ddd; border-image: -webkit-linear-gradient ...

  9. php箭头符号

    ->这个箭头是调用类中的函数  比如  class a  {  function b()  {    echo ’a’;  }  }  $a=new a;  $a->b();  输出:a ...

  10. 第二次作业:找Bug

    引子 我真的想了一个小时,上哪里去找bug.我昨天还留意到一个bug,今天就不见了.灵光不断,我想起来了.我就要找大公司的产品的bug... 第一部分 调研, 评测 体验. <腾讯桌球>是 ...