• 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" />
    
  • 相关阅读:
    JavaScript中{}+{}
    网站性能优化
    C++是如何从代码到游戏的?
    C++是如何从代码到游戏的?
    【力扣】至少是其他数字两倍的最大数 中速题解
    代码编辑器选择Atom还是VScode?
    TIOBE 4 月榜单:少儿编程语言 Scratch 进入 TOP 20
    熟悉一下oncontextmenu事件的知识
    input属性type为file打开文件资源管理器时,如何限制多次选取或只能一次选取的行为
    HTML5的拖放事件
  • 原文地址:https://www.cnblogs.com/linhp/p/6265654.html
Copyright © 2020-2023  润新知