zoukankan      html  css  js  c++  java
  • 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"/>

  • 相关阅读:
    您真的了解javaScript?(3)
    SvUDID实现设备唯一标示
    iOS 获取通讯录权限的时机
    iOS 后台退出app时不执行applicationWillTerminate的临时解决方法
    sqlite 批量插入, 重复插入(更新)
    tableView 显示区域偏移
    socket 粘包问题(转)
    ruby 安装更新
    openssl 升级
    gem 安装&卸载pod
  • 原文地址:https://www.cnblogs.com/bulrush/p/7732997.html
Copyright © 2011-2022 走看看