struts2(二)值栈 threadlocal ogal ui   值栈(重要)和ognl表达式 Threadlocal

值栈(重要)和ognl表达式

1、  只要是一个mvc框架,必须解决数据的存和取的问题

2、  Struts2利用值栈来存数据,所以值栈是一个存储数据的内存结构

3、  把数据存在值栈中,在页面上利用ognl表达式显示出来

讨论的问题

1、  讨论值栈的生命周期

2、  值栈的内存结构

3、  通过什么样的方法把数据放入到值栈中

4、  显示出来

值栈的内存结构

获取值栈的路径

 struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

       说明:

1、  值是一样的,说明只有一个对象

2、  因为有一种是从request域中获取的,所以是一次请求

内存结构

1、  大致图:

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

2、  上面图中的context的放大

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

说明:

        _root:(CompoundRoot)

        _values:(HashMap)

             在这里存放了request,response,session,application等servlet容器的内容

3、_root的放大

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

说明:

    和ValueStack中的root是一致的

值栈的内存总图

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

说明:

     从上图中可以看出valueStack总共分为两个部分:

          对象栈:root

          Map栈:_values

对象栈的存放

1、  Push方法

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

2、  add方法

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

对象栈的提取

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

从上图中可以看出,peek方法为获取对象栈的栈顶的元素

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

对象栈的元素的弹出*(栈顶的数据弹出)

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

作对象栈中的对象

 struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

说明:

     可以利用valueStack.setParameter方法改变对象栈中对象的属性的值

Map栈的存放

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

 通过该方法可以把一个字符串放入到map栈中的request域中

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

通过该方法可以把一个字符串放入到map栈中的application域中

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

通过该方法可以把一个字符串放入到map栈中

package com.itheima09.struts2.action;

import ognl.OgnlContext;

import org.apache.struts2.ServletActionContext;

import com.itheima09.bean.Person;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.CompoundRoot;
import com.opensymphony.xwork2.util.ValueStack;

public class ValueStackAction extends ActionSupport{
    /**
     * 获取值栈
     */
    public String testGetValueStack(){
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        ValueStack valueStack2 = ServletActionContext.getValueStack(ServletActionContext.getRequest());
        ValueStack valueStack3 = (ValueStack)ServletActionContext.getRequest().getAttribute("struts.valueStack");
        System.out.println(valueStack);
        System.out.println(valueStack2);
        System.out.println(valueStack3);
        return SUCCESS;
    }
    
    /**
     * 把一个对象放入到对象栈中
     * @return
     */
    public String testPutObjToObjectStack_1(){
        /**
         * 把一个对象放入到对象栈的栈顶
         */
        ActionContext.getContext().getValueStack().push("aaaa");
        return SUCCESS;
    }
    
    public String testPutObjToObjectStack_2(){
        /**
         * 把一个对象放入到对象栈的栈顶
         */
        ActionContext.getContext().getValueStack().getRoot().add(0,"aaa");
        return SUCCESS;
    }
    
    public String testPutObjToObjectStack_3(){
        /**
         * 把一个对象放入到对象栈的最底部
         */
        ActionContext.getContext().getValueStack().getRoot().add("aaa");
        return SUCCESS;
    }
    
    /**
     * 从对象栈的栈顶提取元素
     * @return
     */
    public String testGetObjFromObjectStack_1(){
        ActionContext.getContext().getValueStack().peek();
        return SUCCESS;
    }
    
    public String testGetObjFromObjectStack_2(){
        ActionContext.getContext().getValueStack().getRoot().get(0);
        return SUCCESS;
    }
    
    /**
     * 从栈顶把对象弹出对象栈
     */
    public String testPopObj_1(){
        ActionContext.getContext().getValueStack().pop();
        return SUCCESS;
    }
    
    /**
     * 从对象栈中清除一个元素
     * @return
     */
    public String testPopObj_2(){
        ActionContext.getContext().getValueStack().getRoot().remove(0);
        return SUCCESS;
    }
    
    /**
     * 把一个对象放入到对象栈中
     * @return
     */
    public String testPutObjectToObjectStack(){
        Person person = new Person();
        person.setPid(1L);
        person.setName("王二麻子");
        //把person放入到了对象栈的栈顶
        ActionContext.getContext().getValueStack().push(person);
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        //通过setParameter方法把对象栈的属性赋值
        valueStack.setParameter("name", "aaaaa");
        //从对象栈中把栈顶的对象提取出来
        person = (Person)ActionContext.getContext().getValueStack().peek();
        System.out.println(person.getName());
        return SUCCESS;
    }
    
    /**
     * 把一个字符串放入到request域中
     */
    public String testPutStrToRequest(){
        ServletActionContext.getRequest().setAttribute("request_aaa", "request_aaa");
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        return SUCCESS;
    }
    
    /**
     * 把一个字符串放入到application域中
     */
    public String testPutStrToApplication(){
        ServletActionContext.getServletContext().setAttribute("application_aaa", "application_aaa");
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        return SUCCESS;
    }
    
    /**
     * 把一个字符串放入到map栈中
     */
    public String testPutStrToMap(){
        ActionContext.getContext().put("aaa", "aaa");
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        return SUCCESS;
    }
}
对象栈和map栈存取数据

Threadlocal

1、  本地线程类

2、  可以存放一个对象

3、  Threadlocal对象只能当前线程访问,其他的线程是不能访问的()

4、  传递参数 主要作用

参数的传递

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

说明:通过参数的传递,一个字符串很容易的从客户端传递到tl1中的tl1方法,再传递到tl2中的tl2方法

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

说明:

    在TL1Super中用到一个字符串

    在TL2Super中用到同样的字符串,但是这两个类是完全松耦合,这个时候要用

    Threadlocal传递数据,因为不管是否是送耦合的,但是可以肯定在同一个线程中。所以可以得到同一个线程threadlocal对象中的数据

Ognl表达式

Debug标签(重要)

       在页面上引入标签库

 struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

可以通过网页的形式把valueStack中值提取出来

关于对象栈:

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

 从上图可以看出来,对象栈的属性来自于对象栈中的每一个对象的属性的get方法

把一个对象放入到对象栈中

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

上述的两个类中都同时有name属性,而且当前请求的action在对象栈中

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

package com.itheima09.struts2.action;

import ognl.OgnlContext;

import org.apache.struts2.ServletActionContext;

import com.itheima09.bean.Person;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.CompoundRoot;
import com.opensymphony.xwork2.util.ValueStack;

public class ValueStackAction extends ActionSupport{
    /**
     * 获取值栈
     */
    public String testGetValueStack(){
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        ValueStack valueStack2 = ServletActionContext.getValueStack(ServletActionContext.getRequest());
        ValueStack valueStack3 = (ValueStack)ServletActionContext.getRequest().getAttribute("struts.valueStack");
        System.out.println(valueStack);
        System.out.println(valueStack2);
        System.out.println(valueStack3);
        return SUCCESS;
    }
    
    /**
     * 把一个对象放入到对象栈中
     * @return
     */
    public String testPutObjToObjectStack_1(){
        /**
         * 把一个对象放入到对象栈的栈顶
         */
        ActionContext.getContext().getValueStack().push("aaaa");
        return SUCCESS;
    }
    
    public String testPutObjToObjectStack_2(){
        /**
         * 把一个对象放入到对象栈的栈顶
         */
        ActionContext.getContext().getValueStack().getRoot().add(0,"aaa");
        return SUCCESS;
    }
    
    public String testPutObjToObjectStack_3(){
        /**
         * 把一个对象放入到对象栈的最底部
         */
        ActionContext.getContext().getValueStack().getRoot().add("aaa");
        return SUCCESS;
    }
    
    /**
     * 从对象栈的栈顶提取元素
     * @return
     */
    public String testGetObjFromObjectStack_1(){
        ActionContext.getContext().getValueStack().peek();
        return SUCCESS;
    }
    
    public String testGetObjFromObjectStack_2(){
        ActionContext.getContext().getValueStack().getRoot().get(0);
        return SUCCESS;
    }
    
    /**
     * 从栈顶把对象弹出对象栈
     */
    public String testPopObj_1(){
        ActionContext.getContext().getValueStack().pop();
        return SUCCESS;
    }
    
    /**
     * 从对象栈中清除一个元素
     * @return
     */
    public String testPopObj_2(){
        ActionContext.getContext().getValueStack().getRoot().remove(0);
        return SUCCESS;
    }
    
    /**
     * 把一个对象放入到对象栈中
     * @return
     */
    public String testPutObjectToObjectStack(){
        Person person = new Person();
        person.setPid(1L);
        person.setName("王二麻子");
        //把person放入到了对象栈的栈顶
        ActionContext.getContext().getValueStack().push(person);
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        //通过setParameter方法把对象栈的属性赋值
        valueStack.setParameter("name", "aaaaa");
        //从对象栈中把栈顶的对象提取出来
        person = (Person)ActionContext.getContext().getValueStack().peek();
        System.out.println(person.getName());
        return SUCCESS;
    }
    
    /**
     * 把一个字符串放入到request域中
     */
    public String testPutStrToRequest(){
        ServletActionContext.getRequest().setAttribute("request_aaa", "request_aaa");
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        return SUCCESS;
    }
    
    /**
     * 把一个字符串放入到application域中
     */
    public String testPutStrToApplication(){
        ServletActionContext.getServletContext().setAttribute("application_aaa", "application_aaa");
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        return SUCCESS;
    }
    
    /**
     * 把一个字符串放入到map栈中
     */
    public String testPutStrToMap(){
        ActionContext.getContext().put("aaa", "aaa");
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        return SUCCESS;
    }
}
值栈操作action

Property标签(重要)

介绍

              输出标签

                    value  指定要输出的内容

                            如果在对象栈中,直接指定属性

                                 也可以直接调用方法

                            如果在map栈中,用#指定

                       如果value属性不写,则默认输出栈顶的元素

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

把一个对象放入到对象栈中,可以利用s:prototype标签的value属性直接访问

该对象的属性。如果对象栈中出现两个相同的属性,则prototype标签的value属性会

从栈顶往下查找,直到找到为止。赋值的为第一个。

 struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

把一个对象放入到map中,再把map放入到对象栈中,在页面上可以利用

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

 struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

可以利用方法来访问利用该标签访问map栈中的元素

 struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

terator标签(重要)

1、  用途:主要用于迭代,可以迭代List,Set,Map,Array

2、  案例

1、  把集合放入到对象栈中

 struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

 2、把list放入到map中

即使在map中,当前在迭代的对象会放在栈顶

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

3、  把list放入到request域中

总结:

1、  如果要迭代一个集合,当前迭代的元素在栈顶

2、  如果要迭代一个map,则当前迭代的元素是entry

3、  Iterator标签中有一个属性status

Ui标签

1、  struts2提供了一套标签机制,由struts2框架把struts2的标签解析成html标签。

2、  在struts2的配置文件中,增加

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

在struts2的配置文件中加入如下的内容

<constant name="struts.ui.theme" value="simple"></constant>

由struts2容器翻译过程来的html代码和struts2标签的代码就能保持一致。

<constant name="struts.devMode" value="true"></constant>    xml配置文件改动后 立即生效  开发用  

Select标签

1.静态资源

<td><s:select list="{'山西省','河南省','四川省'}" value="{'山西省'}"></s:select></td>
                      <td><s:select list="#{1:'山西省',2:'河南省',3:'四川省'}" value="#{2:'河南省'}"></s:select></td>
View Code

2.动态资源, 从map栈中取

<td><s:select list="#provinces" listKey="pid" listValue="name"/></td>
                      <!-- 
                          listKey  为option元素的value属性的值
                          listValue  option元素的文本内容
                          name
                              该属性的值用来获取选中的元素
                              用于回显
                       -->
View Code

checkbox

回显:  在jsp中显示栈值中的数据(ogal表达式)

如果要回显的内容在map栈中,不能根据name属性进行回显,必须用value属性进行回显<td><s:textfield name="username" value="%{#user.username}"></s:textfield></td>
如果把要回显的对象放入到对象栈中,则页面上可以根据name进行回显<s:textfield name="username"></s:textfield>

 一般情况下,如果要回显一个对象,则把该对象放入到对象栈中

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
  </head>
  
  <body>
        <s:form action="">
            <table>
                  <tr>
                      <td>用户名</td>
                      <!-- 
                          s:select  s:checkboxlist
                            这些标签中的list属性的值可以直接跟ognl表达式
                          一般情况下,表单中的元素的value属性都不能直接跟ognl表达式
                          可以使用%{ognl表达式}
                          如果要回显的内容在map栈中,不能根据name属性进行回显,必须用value属性进行回显
                              <td><s:textfield name="username" value="%{#user.username}"></s:textfield></td>
                                如果把要回显的对象放入到对象栈中,则页面上可以根据name进行回显
                              <s:textfield name="username"></s:textfield>
                               一般情况下,如果要回显一个对象,则把该对象放入到对象栈中
                       -->
                      <td><s:textfield name="username"></s:textfield></td>
                  </tr>
                  <tr>
                      <td>爱好</td>
                      <!-- 
                          用name进行回显
                       -->
                      <td><s:checkboxlist list="#hobbies" listKey="hid" listValue="name" name="hids"/></td>
                  </tr>
              </table>
        </s:form>
  </body>
</html>
回显

1、  如果把要回显的数据放入到map栈中,则必须根据value进行回显

Value=”%{ognl表达式}”

2、  一般情况下,应该把回显的数据放入到对象栈中,因为页面上可以直接根据name进行回显

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal

3、  因为当前请求的action在对象栈中,所以可以利用action中的属性进行回显,action中的属性必须有get方法。

4、  Checkbox的回显

struts2(二)值栈 threadlocal ogal ui
 
值栈(重要)和ognl表达式
Threadlocal