• Struts2知识点小结(三)--值栈与ognl表达式


    1.问题一 : 什么是值栈 ValueStack
        
        回顾web阶段 数据交互问题?
            客户端提交数据  到  服务器端    request接受数据+BeanUtils实体封装
            服务器端数据 在页面上显示        在服务器端将数据存储到request域中  页面中通过el+jstl完成数据展示
            
        struts2阶段,数据交互问题?
            客户端提交数据  到  服务器端    属性驱动和模型驱动
            服务器端数据 在页面上显示        在服务器端将数据存储到值栈中    在页面中通过ognl+struts2标签数据展示
            
        request域    等于    值栈
        el表达式    等于    ognl表达式
        jstl标签    等于    struts2标签
        
        
        值栈是什么?
            值栈是服务器与客户端进行数据交互的数据中心,用于存储数据
            在服务器将数据存储到值栈中 在页面中从值栈取出数据进行展示
            
            值栈ValueStack是Struts2提供接口规范,于此同时也提供了该接口的实现OgnlValueStack
            
        值栈的生命周期?
            Action          ActionContext        ValueStack
                1                1                    1
            
            
            Action:多例的
                创建:每次访问都会创建一个新的的Action
                销毁:响应结束该Action销毁
                
            
    2.问题二 : 值栈的内部结构
        获得值栈对象
            ActionContext context = ActionContext.getContext();
            VAlueStack valueStack = context.getValueStack();
            
        值栈的内部结构:
            Root栈:ArrayList
            context栈:map
            

       


    3.问题三 : 值栈对象何时创建?ValueStack 和 ActionContext是什么关系
        源码分析:
            --->StrutsPrepareAndExecuteFilter
            --->public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            --->prepare.createActionContext(request, response);
            --->ValueStack stack = createValueStack();
            
        ActionContext内部维护值栈的引用
        
    4.问题四 : 如何获得值栈对象ValueStack
        第一种方式:
            ActionContext context = ActionContext.getContext();
            VAlueStack valueStack = context.getValueStack();
            
        第二种方式:
            通过request域对象 request.getAttribute("struts.valueStack");
            
            源码:
                --->StrutsPrepareAndExecuteFilter
                --->public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                --->execute.executeAction(request, response, mapping);
                --->dispatcher.serviceAction(request, response, mapping);
                --->request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
                    public static final String STRUTS_VALUESTACK_KEY = "struts.valueStack"

    5.问题五 : 如何手动向值栈保存数据
        5.1 向Root栈存储数据
            //获得值栈对象
            ValueStack valueStack = ActionContext.getContext().getValueStack();
            //获得内部的Root栈
            CompoundRoot root = valueStack.getRoot();

            //存数据
            root.add("itcast");        //存储到尾部
            root.add(0, "itheima"); //存储到头部(栈顶)

            //CompoundRoot的存取数据的API
            root.push("xxx"); //压栈 add(0, o);
            root.peek(); //获得栈顶的值 return get(0);
            root.pop(); //弹栈 return remove(0);
        5.2 向context栈存储数据
            //获得值栈对象
            ValueStack valueStack = ActionContext.getContext().getValueStack();
            //获得context栈
            Map<String, Object> map = valueStack.getContext();
            
            map.put("xxx", "XXX");
            map.get("xxx");
            
        5.3 valueStack对象维护着向值栈存取数据的API
            valueStack.push();
            valueStack.set();
            valueStack.findValue();
           
    6.问题六 : struts2框架会将哪些数据自动保存到值栈中
        引入struts2的标签<s:debug/>   该标签可以在页面中直观看到值栈的内部数据
        
        6.1 struts2框架会自动将哪些数据存储到Root栈
            将当前访问的Action对象自动压栈
                作用:Action的get方法的属性值 可以通过ognl表达式方便获取
            将当前模型对象自动压到栈顶
                作用:模型对象压到栈顶 通过ognl表达式方便取出模型对象的属性值
        
        6.2 struts2框架会自动将哪些数据存储到context栈
            request对象
            response对象
            各种域数据
            请求参数
            ... ...
            
            维护本次请求的所有相关数据
        
    7.问题七 : 如何取值栈的数据 (Ognl+struts2标签)
        7.1 取出普通数据
            注意:什么符号都不加 代表从Root栈取值
            <s:property value="ognl表达式"/>
            
            <h1>取出普通数据name</h1>
            <s:property value="name"/>
            <h1>取出user中的name</h1>
            <s:property value="user.name"/>
            
            
            注意:#代表直接从context栈取值
            <s:property value="#ognl表达式"/>
            
        7.2 遍历集合数据
            <!--
            会将集合中的每一个元素对象 依次临时存储到栈顶
             -->
            <%-- <s:iterator value="userList">
                <s:property value="name"/>==<s:property value="age"/><br/>
            </s:iterator> --%>
            
            <!--
                var: 变量名称  临时使用var指定的字符串作为key在context栈存储一份
             -->
            <s:iterator value="userList" var="user">
                <s:property value="#user.name"/>==<s:property value="#user.age"/><br/>
            </s:iterator>


    8.问题八 : 为什么 EL也能访问值栈中的数据 (面试)
        原因:StrutsRequestWrapper
        ${} 底层调用getAttribute方法
        源码:
            request = prepare.wrapRequest(request);
            request = dispatcher.wrapRequest(request);
            
            //BufferedReader reader = new BufferedReader(new FileReader());
            StrutsRequestWrapper request = new StrutsRequestWrapper(request);
            
            增强的是getAttribute方法:
            public Object getAttribute(String key) {
                //调用原来的request的方法
                Object attribute = super.getAttribute(key); //从request域中获得值
                if (attribute == null) {
                    attribute = stack.findValue(key);
                }
                return attribute;
            }

  • 相关阅读:
    23种设计模式
    外部排序:选择置换、败者树
    java代理模式
    java中抽象类和接口的异同(原文作者:博客园 海子)
    java中的垃圾回收
    进程
    C标准库-数值字符串转换与内存分配函数
    文件操作
    字符串操作
    C指针(二)
  • 原文地址:https://www.cnblogs.com/itworkerlittlewrite/p/9442189.html
Copyright © 2020-2023  润新知