• struts2 值栈分析


    一、值栈分为两个逻辑部分

    1 Map 栈: 实际上是 OgnlContext 类型, 是个 Map, 也是对 ActionContext 的一个引用. 里边保存着各种 Map: 
              如: requestMap, sessionMap, applicationMap, parametersMap, attr
             
    2 对象栈: 实际上是 CompoundRoot 类型, 是一个使用 ArrayList 定义的栈. 里边保存各种和当前 Action 实例相关的对象.
              是一个数据结构意义的栈.
    

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

    1、值栈中的属性值:

    • 对于对象栈: 对象栈中某一个对象的属性值
    • Map 栈: request, session, application 的一个属性值 或 一个请求参数的值.

    2、读取对象栈中对象的属性:

    1. 若想访问 Object Stack 里的某个对象的属性. 可以使用以下几种形式之一:

    object.propertyName ;

    object['propertyName'];

    object["propertyName"]

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

    [0].message

    1. [n] 的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象.(也就是说,0找不到,就找1,以此类推)

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

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

    3、默认情况下,Action 对象会被 Struts2 自动的放到值栈的栈顶

    如:我这里写了一个action

    public class Product {
    	
    	private Integer productId;
    	private String productName;
    	private String productDesc; 
    	private double productPrice;
    	
    	...省去getter,setter
    	
    	// 会返回到 details.jsp
    	public String save(){
    	    // 请求save 时,带上参数 
    		System.out.println("save: " + this);
    		return "success";
    	}
    }
    

    下面是关于details.jsp

    <s:debug></s:debug>
    
    <br> ProductName:<%=request.getAttribute("productName")%>
    <br> ProductDesc: ${productDesc }
    <br> ProductPrice: ${productPrice }
    

    页面的效果为:

    ProductName:abc
    ProductDesc: 123 
    ProductPrice: 123.0 
    

    查看debug可以看出,Product被放到了栈顶

    image

    如果使用<s:property >标签来获取也是可以的( [] 可以省略 )

    ProductName: <s:property value="[0].productName" />
    ProductDesc: <s:property value=".productDesc" />
    

    4、通过例子,直观ValueStack(对象栈)

    还是使用原来的action

    public class Product {
    	
    	private Integer productId;
    	private String productName;
    	private String productDesc;
    	private double productPrice;
    	
    	// 省去getter,setter
    	
    	// 前台请求的参数为: productName=abc&productDesc=cde&productPrice=123
    	public String save(){
    		System.out.println("save: " + this);
    		
    		//1. 获取值栈
    		ValueStack valueStack = ActionContext.getContext().getValueStack();
    		
    		//2. 创建 Test 对象, 并为其属性赋值
    		Test object = new Test();
    		object.setProductDesc("AABBCCDD");
    		object.setProductName("ABCD");
    		
    		//3. 把 Test 对象压入到值栈的栈顶!
    		valueStack.push(object);
    		
    		return "success";
    	}
    	
    }
    

    关于Test类如下

    public class Test {
    
    	private String productName;
    	private String productDesc;
    
        // 省去getter,setter
    }
    

    接下来,查看页面信息的debug

    image

    从这里可以看出,此时Test对象已经在栈顶,所以
    ${productName}就会获取AABBCCDD

    而如果要获取Product对象,就要使用 <s:property value="[1].productName" />

    5、使用<s:property /> 获取map栈里面的值

    也就是获取request,sesssion,application等

    <s:property value="#request.product.productName" />
    

    直接用EL表达式获取也可以

    ${requestScope.product.productName}
    

    三、ongl表达式读取静态字段或方法(了解)

    可以利用 OGNL 调用 (了解)

    • 任何一个 Java 类里的静态字段或方法.
    • 被压入到 ValueStack 栈的对象上的公共字段和方法

    默认情况下, Struts2 不允许调用任意 Java 类静态方法, 需要重新设置 struts.ognl.allowStaticMethodAccess 标记变量的值为 true.

    <s:property value="@java.lang.Math@PI" />
    
  • 相关阅读:
    【BZOJ 2124】【CodeVS 1283】等差子序列
    【BZOJ 1036】【ZJOI 2008】树的统计Count
    【BZOJ 1901】【ZJU 2112】Dynamic Rankings
    【BZOJ 3924】【ZJOI 2015】幻想乡战略游戏
    【BZOJ 4103】【THUSC 2015】异或运算
    【BZOJ 4513】【SDOI 2016】储能表
    【HDU 3622】Bomb Game
    【BZOJ 3166】【HEOI 2013】Alo
    【BZOJ 3530】【SDOI 2014】数数
    【BZOJ 4567】【SCOI 2016】背单词
  • 原文地址:https://www.cnblogs.com/linhp/p/6265654.html
Copyright © 2020-2023  润新知