Struts框架笔记03_OGNL表达式与值栈

Struts框架笔记03_OGNL表达式与值栈_第1张图片
结构图

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文件中配置核心过滤器

  
    struts
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
  
  
    struts  
    /*
  
  • 引入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"%>




Insert title here


OGNL在Struts2环境中的入门

调用对象的方法

1.3.2 访问对象的静态方法

  • 静态方法访问在Struts2中默认是关闭的,需要手动开启一个常量
  • 在配置文件中开启常量

    
    

  • JSP

OGNL在Struts2环境中的入门

调用对象的方法

调用对象的静态方法

  • 测试:访问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区域。
Struts框架笔记03_OGNL表达式与值栈_第2张图片
值栈的内部结构

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">
      /demo1/success.jsp
     
    
  • 跳转页面success.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib uri="/struts-tags"  prefix="s"%>
    
    
    
    
    Insert title here
    
    
    

    查看值栈的内部结构

  • 访问http://localhost/Struts2_day03/valueStackDemo2.action

    Struts框架笔记03_OGNL表达式与值栈_第3张图片
    从值栈中取数据

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

    操作值栈

    <%-- --%>
  • 访问http://localhost/Struts2_day03/valueStackDemo3.action

    Struts框架笔记03_OGNL表达式与值栈_第4张图片
    从值栈中取数据

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 list = new ArrayList();
          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"%>
    
    
    
    
    Insert title here
    
    
    

    获取值栈的数据











  • 测试:访问http://localhost/Struts2_day03/valueStackDemo4.action

    Struts框架笔记03_OGNL表达式与值栈_第5张图片
    获取值栈的数据

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"%>




Insert title here


#的用法

<% request.setAttribute("name", "李斌"); %>
  • 在页面能获取到request中存储的数据

3.1.2 使用#号构建Listmap集合

  • ../WebContent/demo2/test.jsp

构建list集合

--

构建Map集合1

--

构建Map集合2

--

实例1


实例2

  • 访问http://localhost/Struts2_day03/demo2/test.jsp

    Struts框架笔记03_OGNL表达式与值栈_第6张图片
    使用#构建集合

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"%>
    
    
    
    
    Insert title here
    
    
    

    %的使用

    <% request.setAttribute("name", "罩子龙"); %> 姓名:
    • 访问:http://localhost/Struts2_day03/demo2/test2.jsp
    Struts框架笔记03_OGNL表达式与值栈_第7张图片
    %的使用

3.3 $号

  • 在配置文件中使用$

你可能感兴趣的:(Struts框架笔记03_OGNL表达式与值栈)