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

  • 相关阅读:
    Kubernetes 集成研发笔记
    Rust 1.44.0 发布
    Rust 1.43.0 发布
    PAT 甲级 1108 Finding Average (20分)
    PAT 甲级 1107 Social Clusters (30分)(并查集)
    PAT 甲级 1106 Lowest Price in Supply Chain (25分) (bfs)
    PAT 甲级 1105 Spiral Matrix (25分)(螺旋矩阵,简单模拟)
    PAT 甲级 1104 Sum of Number Segments (20分)(有坑,int *int 可能会溢出)
    java 多线程 26 : 线程池
    OpenCV_Python —— (4)形态学操作
  • 原文地址:https://www.cnblogs.com/itworkerlittlewrite/p/9442189.html
Copyright © 2011-2022 走看看