Struts2 ---值栈

 

Strut2的Action类通过属性可以获得所有相关的值,如请求参数属性值等。要获得这些参数值,我们要做的唯一一件事就是在Action类中声明与参数同名的属性。在Struts2调用Action类的Action方法(默认是execute方法)之前,就会为相应的Action属性赋值。要完成这个功能,有很大程度上,Struts2要依赖于ValueStack对象。这个对象贯穿整个Action的生命周期,每个Action类的对象实例会拥有一个ValueStack对象。

       当Struts2接收到一个.action的请求后,会先建立Action类的对象实例,但并不会调用Action方法,而是先将Action类的相应属性放到ValueStack对象的顶层节点(ValueStack对象相当于一个栈)。只是所有的属性值都是默认的值,如String类型的属性值为null,int类型的属性值为0等。在处理完上述工作后,Struts 2就会调用拦截器链中的拦截器,这些拦截器会根据用户请求参数值去更新ValueStack对象顶层节点的相应属性的值,最后会传到Action对象,并将ValueStack对象中的属性值,赋给Action类的相应属性。当调用完所有的拦截器后,才会调用Action类的Action方法。ValueStack会在请求开始时被创建,请求结束时消亡。

 

1. 关于值栈:

1). helloWorld 时, ${productName} 读取 productName 值, 实际上该属性并不在 request 等域对象中, 而是从值栈中获取的.

2). ValueStack:

I.  可以从 ActionContext 中获取值栈对象
II. 值栈分为两个逻辑部分

    > Map 栈: 实际上是 OgnlContext 类型, 是个 Map, 也是对 ActionContext 的一个引用. 里边保存着各种 Map:
             requestMap, sessionMap, applicationMap, parametersMap, attr
             
    > 对象栈: 实际上是 CompoundRoot 类型, 是一个使用 ArrayList 定义的栈. 里边保存各种和当前 Action 实例相关的对象.
                       是一个数据结构意义的栈.
     这三个方法就是栈的理解               
    public Object peek(){
        return get(0);    //获取第一个对象
    }
    public Object pop(){
        return remove(0); //出栈,把第一个对象取出来
    }
    public void push(Object o){
        add(0,o);  //压栈,把对象放到第一个位置。
    }

 2. Struts2 利用 s:property 标签和 OGNL 表达式来读取值栈中的属性值
 
 1). 值栈中的属性值:
 
     > 对于对象栈: 对象栈中某一个对象的属性值
     
     > Map 栈: request, session, application 的一个属性值 或 一个请求参数的值.
     
 2). 读取对象栈中对象的属性:
 
     > 若想访问 Object Stack 里的某个对象的属性. 可以使用以下几种形式之一:
        
      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" />
 
 3). 默认情况下, Action 对象会被 Struts2 自动的放到值栈的栈顶.

例子步骤:

·1:index.jsp主页面上

 <a href="studentAction">ValueStack</a>     //对应的是struts.xml中 action中的name

2:struts.xml

<package name="testValueStack"  extends="struts-default">
        <action name="studentAction" class="com.struts2.students.StudentAction">
            <result name="success" >/pages/testValueStack.jsp</result>
        </action>
    </package>

3:创建一个student对象。

package com.struts2.students;

public class Student {
    private String Name;
    private String Age;
    private String Banji;
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public String getAge() {
        return Age;
    }
    public void setAge(String age) {
        Age = age;
    }
    public String getBanji() {
        return Banji;
    }
    public void setBanji(String banji) {
        Banji = banji;
    }
    @Override
    public String toString() {
        return "Student [Name=" + Name + ", Age=" + Age + ", Banji=" + Banji
                + "]";
    }
}

然后写一个StudentAction

package com.struts2.students;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.ValueStack;

public class StudentAction {
    public String execute(){
        //1:获取值栈
        ValueStack vs=ActionContext.getContext().getValueStack();
        //2:创建对象,并赋值
        Student student=new Student();
        student.setAge("19");
        student.setBanji("二班");
        student.setName("陈王");
        //3:把student放到Value Stack中
        /*vs.getRoot().add(student);*/
        vs.push(student);    //这两种方式都是放到Value Stack  中
        
        //4:把student放到Stack Context中
        vs.getContext().put("student", student);
        // 默认放到request中 <s:property value="#request.student2.Name"/>
return "success"; } }
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>TestValueStack</title>
</head>
<body>
    <h1>TestValueStack</h1>
    
        A:<s:property value="[0].Name"/><br/>  <!--存在ValueStack中的,取属性的值。可以直接取,也可以用下标  -->
        B:<s:property value="Age"/><br/>
        C:<s:property value="Banji"/><br/>
        <s:debug></s:debug>
        <s:property value="#student.Name"/>   <!-- 存在Stack Context中的。用#引用.属性值 -->
      <s:property value="#request.student2.Name"/>   是同样的结果
</body> </html>

 

 这是两个放到值栈和Stack Context中。

放到Stack Context中  值栈就没有值

放到值栈中

 **当两个对象分别放到Value Stack 和Stack Context 中的时候。取的是值栈中的内容

public class StudentAction {
    public String execute(){
        //1:获取值栈
        ValueStack vs=ActionContext.getContext().getValueStack();
        //2:创建对象,并赋值
        Student student=new Student();
        Student student2=new Student();
        student2.setAge("20");
        student2.setBanji("三班");
        student2.setName("毅力");
        student.setAge("19");
        student.setBanji("二班");
        student.setName("陈王");
        //3:把student放到Value Stack中
        /*vs.getRoot().add(student);*/
        vs.push(student);
        
        //4:把student放到Stack Context中
        vs.getContext().put("student2", student2);
        return "success";
    }
}

student 放到值栈中。student2放到Context中

 

 

 同一个对象放到值栈,或者Stack Context中的时候。谁在后面显示谁。

Student student=new Student();
        Student student2=new Student();
        student.setAge("29");
        student.setBanji("三班");
        student.setName("陈毅");
        student2.setAge("20");
        student2.setBanji("三班");
        student2.setName("毅力");
        student.setAge("19");
        student.setBanji("二班");
        student.setName("陈王");

这里显示的是陈王

 **:把值放到sessionMap中,Action类实现SessionAware接口。

package com.struts2.students;

import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.ValueStack;

public class StudentAction implements SessionAware{
    private Map<String,Object> session;
    public void setSession(Map<String, Object> arg0) {
        this.session=arg0;
    }

    public String execute(){
        //1:获取值栈
        ValueStack vs=ActionContext.getContext().getValueStack();
        //2:创建对象,并赋值
        Student student=new Student();
        
        student.setAge("19");
        student.setBanji("二班");
        student.setName("陈王");
        
        /*//3:把student放到Value Stack中
        vs.getRoot().add(student);
        vs.push(student);*/
        
        //4:把student放到Stack Context中
        session.put("student", student);
        return "success";
    }
}

在页面上取值:

<s:property value="#session.student.Name"/>

 

posted @ 2017-10-25 23:13  陆伟  阅读(167)  评论(0编辑  收藏  举报