美文网首页Java 杂谈
Struts2学习笔记 | 值栈和OGNL

Struts2学习笔记 | 值栈和OGNL

作者: 一颗白菜_ | 来源:发表于2019-08-01 18:15 被阅读1次

1.值栈(ValueStack)

引入值栈

在部署第一个Struts2时,Struts2学习笔记 | 部署第一个Struts2项目及其项目解析(IDEA版)

Demo里面用${productName}读取productName值时,实际上该属性并不在request等域对象中,而是从值栈中获取的。

值栈的概述

  • 贯穿整个Action的生命周期(每个Action类的对象实例都有一个ValueStack对象),相当于一个数据的中转站,在其中保存当前Action对象和其它相关的对象

  • Struts框架把ValueStack对象保存在名为"struts.valueStack"的请求属性中

值栈对象有两个逻辑部分

  • ContextMap

是一个Map,实际上是OgnlContext类型。
Struts把各种各样的映射关系(一些Map类型的对象)压入ContextMap中。
实际上就是对ActionContext的一个引用。

Struts会把下面这些映射压入ContextMap中:

  • parameters :该Map中包含当前请求的请求参数
  • request:该Map中包含当前request对象中的所有属性
  • session:该Map中包含当前session对象中的所有属性
  • application:该Map中包含当前application对象中的所有属性
  • attr:该Map按如下顺序来检索某个属性:request,session,application
  • ObjectStack(对象栈)
  • 实际上是CompoundRoot类型,是一个使用ArrayList定义的栈。
  • 类似于数据结构中学到的栈,是一个真实意义上的栈
  • Struts把Action和相关对象压入ObjectStack中

2.OGNL(对象-图导航语言)

  • 在JSP页面上可以利用OGNL访问到值栈(ValueStack)里的对象属性

  • 若希望访问值栈中ContextMap中的数据,需要给OGNL表达式加上一个前缀字符#,如果没有前缀字符#,搜索将在ObjectStack里进行

  • 可以利用OGNL来调用字段和方法


3.关于值栈中的属性值

  • Struts2利用<s:property>标签和OGNL表达式来读取值栈中的属性值

  • 对于对象栈
    读取的是某一个对象的属性值

  • 对于Map栈
    读取的是request,session,application的一个属性值或一个请求参数的值


4.利用property标签和OGNL读取对象栈中对象的属性

  • 若想访问ObjectStack里的某个对象的属性,可以使用以下几种形式之一
    object.propertyName
    object['propertyName']
    object["propertyName"]
    推荐使用第一种

  • ObjectStack里的对象可以通过一个从零开始的下标来引用,ObjectStack里的栈顶对象可以用[0]来引用,它下面的那个对象可以用[1]引用
    例如:[0].message

  • [n]的含义是从第n个开始搜索,而不是只搜索第n个对象

  • 若从栈顶对象开始搜索,则可以忽略下标部分:message

  • 结合s:property标签
    例如<s:property value="[0].message" /><s:property value="message" />

  • 默认情况下,Action对象会被Struts2放在对象栈顶.

  • 一个示例

<!-- 读取栈顶对象的productDesc-->
<s:property value="[0].productDesc" />
<br><br>
<!-- 读取栈顶向下一个对象的productPrice-->
<s:property value="[1].productPrice" />

5.利用property标签和OGNL读取ContextMap里的对象的属性

  • 若想访问ContextMap里的某个对象的属性,可以使用以下几种形式之一
    #object.propertyName
    #object['propertyName']
    #object["propertyName"]

  • 示例
    返回session中的code属性:#session.code
    返回request中的customer属性的name属性值:#request.customer.name
    返回域对象(按照request,session,application的顺序)的lastAccessDate属性:#attr.lastAccessDate

  • Demo

<!-- 读取session域中的product对象的productPrice属性值-->
ProductPrice2 : <s:property value="#session.product.productPrice" />
<br><br>
<!-- 读取request域中的test对象的productPrice属性值-->
ProductPrice3 : <s:property value="#request.test.productPrice" />

6.调用字段和方法

  • 可以利用OGNL来调用:
  • 任何一个Java类里的静态字段或方法
  • 被压入到ValueStack栈的对象上的公共字段和方法
  • 默认情况下,Struts2不允许调用任意的Java类静态方法,需要在struts.xml文件中设置属性<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>

  • 调用静态字段或方法的语法如下所示
    调用一个类的字段:@fullyQualifiedClassName@fieldName
    示例:<s:property value="@java.lang.Math@PI" />
    调用一个类的方法:@fullyQualifiedClassName@methodName(argumentList)
    示例:<s:property value="@java.lang.Math@cos(0)" />

  • 调用一个实例字段或方法的语法,其中object是ObjectStack栈里的某个对象的引用
    调用一个实例字段:object.fieldName
    调用一个实例方法:object.methodName(argumentList)


7.访问数组类型的属性

  • 有些属性将返回一个对象数组而不是单个对象,可以像读取任何其他对象属性那样读取他们,这种数组型属性的各个元素以逗号分隔,并且不带方括号

  • 可以使用下标访问数组中指定的元素:colors[0]
    *可以通过其length字段查出给定数组中有多少个元素
    colors.length

  • Demo

<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <!-- 调用数组对象的属性 -->
    <%
        String [] names = new String[]{"aa","bb","cc","dd"};
        request.setAttribute("names",names);
    %>
    <br><br>
    length : <s:property value="#attr.names.length" /> <!-- 打印4 -->
    <br><br>
    names[2] : <s:property value="#attr.names[2]" /> <!-- 打印cc-->
    <br><br>
</body>
</html>


8.访问Map类型的属性

  • 读取一个Map类型的属性将以如下所示的格式返回它所有的键值对
    {key1 = value1,key2 = value2, ... ,keyn = valuen}
  • 若希望检索出某个Map的值,需要使用如下格式:map[key]
  • 可以使用sizesize()得出某个给定的Map的键值对的个数
  • 可以使用isEmptyisEmpty()检查某给定Map是不是空

Demo

<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <!-- 使用OGNL访问Map -->
    <%
        Map<String,String> letter = new HashMap <String,String>();
        request.setAttribute("letters",letter);
        letter.put("aa","a");
        letter.put("bb","b");
    %>
    <s:property value="#attr.letters.size" />
    <br><br>
    <s:property value="#attr.letters['aa']" />
</body>
</html>

相关文章

网友评论

    本文标题:Struts2学习笔记 | 值栈和OGNL

    本文链接:https://www.haomeiwen.com/subject/dasqdctx.html