• struts 值桟问题


    一、拦截器的初始化

         如图所示呢,在一次请求过程中,拦截器首先会创建以及初始化一个值栈对象以供使用。初始化过程中,在Map对象里面放了request=,session=,application=,sttr=,parameters=,....;在Stack里放了action对象和其他一些对象(注意对象栈是先进后出,类似弹匣)。由此可见值栈的生命周期是一次请求。

        另外的拦截器,比如说ModelDriven和Params也会对值栈对象进行操作。ModelDriven的初始化会把model压到栈顶

    Params的初始化会把参数设置到值栈对象里,从栈顶开始先查找对象栈里对象的属性,找到就初始化进去,找不到再放到Map的parameters里面。    例如参数是这样:xx.action?id=3&name=ab&age=20&aaa=100,而栈中从栈顶的对象初始化依次为model(id=3 name=ab)、action(id age=20),而aaa参数会放到Map的parameters里面。

    二、操作值栈

       1.在action类中对值栈的操作

         操作Map:  ActionContext.getContext()

                           .put(k, v)

                           .get(k)  

                          或者

                           ActionContext.getContext().getValueStack()

                           .put(k, v)

                           .get(k)

     

         操作Stack: ActionContext.getContext.getValueStack()

                              .push(obj)

                             .pop()

     

          2.在Result中操作值栈(大多在jsp文件中的操作)

          通过使用OGNL表达式操作值栈

           格式:struts.xml中,格式如${ognl}

                       Jsp文件中,格式如%{ognl},而且必须写在struts2的自定义标签的属性中,在外面不会被解析

           语法: user                 = findValue("user") *

                       #user               = map.get("user")

                       #user.name     = map.get("user").getName()

             * findValue()的查找顺序:

            ①从对象栈的栈顶开始查找对象的属性,找到返回

            ②如果对象栈中找不到,进Map查找对应key,返回value,找到返回

        

    例子:                  

    [html] view plain copy
     
    1. <span style="font-size:18px;background-color: rgb(255, 255, 255);"><s:iterator value="#roleList">  
    2.     <s:property value="id"/>,  
    3.     <s:property value="name"/>,  
    4.     <s:property value="description"/>,  
    5.     <s:a action="role_delete?id=%{id}" onclick="return confirm('确定要删除吗?')">删除</s:a>  
    6.     <s:a action="role_editUI?id=%{id}">修改</s:a>  
    7.     <br/>  
    8. </s:iterator></span>  

        在值栈的Map里面有roleList的List,取出来循环

        循环标签还有个特定的功能,循环一次开始后,会把对象拿到栈顶,因此id,name,dedcription会取到当前对象的属性,这里的“%{}”可以省略。


    看官看到这里会有一问:

    EL表达式可以使用值栈吗?

           EL表达式原本的查找顺序为:

        page,request,session,application,找到返回。

        值栈并不在EL表达式的作用范围之内,因此不能使用。但是

     

        struts2对request对象进行了增强,即StrutsRequestWrapper对象,里面重写了getAttribute()方法:在request找不到之后到值栈里面找,因此

    EL表达式的查找顺序变为:page,request,valueStack.findValue(),session,application。

    所以上述例子也可以写为:

    [html] view plain copy
     
      1. <s:iterator value="#roleList">  
      2.     ${id},  
      3.     ${name},  
      4.     ${description},  
      5.     <s:a action="role_delete?id=%{id}" onclick="return confirm('确定要删除吗?')">删除</s:a>  
      6.     <s:a action="role_editUI?id=%{id}">修改</s:a>  
      7.     <br/>  
      8. </s:iterator>  

    页面一个请求发送过来,依次经过一系列拦截器(处理公共部分,如:往数据中心(值栈)填充数据,所处理工作与业务无关),ActionResult

    1,经过一系列拦截器

    介绍其中的两个拦截器:ModelDrivenParams;

     

    ——一个请求过来,首先创建一个值栈对象,经过初始化,然后Map和对象栈中放入一些数据

    (1)值栈的结构:

    (2)Map和对象栈中分别存入什么数据:

    Map中:request=session=…application=…attr=…,parameters=…

    对象栈中:action对象,…

    初始化完之后,还会经过很多拦截器,其中一个拦截器ModelDriven(封装model,把model放入对象栈的栈顶),一个拦截器Params(参数封装,放入参数)

    (1)经过拦截器

    (2)再经过ModelDriven拦截器:

       Action中实现ModelDriven<>,并实现它的方法:

       Public class RoleActionextends ActionSupport implements ModelDriven<Role>{

            private Role model = new Role();

            private Role getModel(){   //获取栈顶的model对象

               return model;

            }

       }

     

    ModelDriven的作用:model对象放入对象栈栈顶(原来栈顶是action,现在栈顶是model)

    (3)经过拦截器

    (4)再经过Params拦截器

       Params拦截器的作用:封装参数。

       如何封装?——做了两件事:第一,先到对象栈中封装;第二,再到Map中封装;

       例子:假如,现在对象栈中有model对象在(含有idname属性)在栈顶,action对象(含有idage属性);页面访问地址:xx.action?id=3&name=ab&age=20&xx=00;

       经过Params拦截器时,它如何将参数封装?

    ——先从栈顶开始找,依次找到idnameage属性,通过各自的Set方法依次设值id=3,name=ab,age=20(注:虽然对象栈中有两个id属性,但是由于model对象的id属性在栈顶,所以找到此id属性就设值,不会继续往下找),但是对象栈中没有xx属性,于是栈中就没有这个参数了,通过对象栈就无法得到xx参数,但是Map中有parameters,可以把所有参数放入parameters中,无论在对象栈中有没有写属性,在parameters中都能得到

    ——经过一系列拦截器之后,此时数据中心就有了数据,那我们就可以从中获取数据(ActionJsp中均可从中获取并使用)

    2,思考:值栈对象作用范围是什么?

    ——一次请求。因为每发送一个请求过来,都要经过这样一系列过程:拦截器(往值栈中压入数据)——>Action——>Request 

    3,细节扩充:

    (1)由值栈对象,如何操作Map

    ——ActionContext.getContext()

                                .put(k,v);//Map中放入数据

                                .get(k);//Map中获取数据

    或:ActionContext.getContext.getValueStack()

                                              .put(k,v);//Map中放入数据

                                              .get(k);//Map中获取数据

    (2)有了值栈对象,如何操作对象栈

    ——ActionContext.getContext().getValueStack()

                                             .push(obj);//向对象栈中放入数据

                                             .pop();//从对象栈中获取数据

    (3)所以,值栈中有了对象,Action中如何使用栈中的数据:

    ——通过ActionContext()操作Map,操作对象栈

    (4)所以,值栈中有了对象,jsp中如何使用栈中的数据:

    ——通过OGNL表达式获取

    OGNL表达式的格式和语法:

    格式:

    (1)Struts.xml中的格式为:${ongl};

    (2)Jsp中的格式为:%{ongl};

    (注:只能写在Struts2的自定义标签的属性中)

    语法:

    user =findValue("user");//从栈中获取user属性

    #user = map.get("user"); //Map中获取user对象

    #user.name=map.get("user").getName();//Map中获取user对象的name属性

    (findvalue(expr))的查找顺序:

    (1)从对象栈中查找指定名称的属性,从栈顶开始向下找,找到后就返回;

    (2)如果从对象栈中没有找到属性,则从Map中查找对应的key值,找到后就返回。

    例子:


    4,总结

        通过此篇博客,我们需要了解什么?
    (1)页面一个请求过来,Struts2中依次经过了哪几个过程?
        —— 一系列拦截器——>Action——>Request;
    ——ModelDriven和Params拦截器分别的主要作用;
    (2)值栈的概念?
    ——值栈的结构:对象栈、Map;
    ——对象栈、Map分别存放什么数据;
    (3)(1)和(2)是如何结合在一起的?
    ——请求过来,一开始经过拦截器,初始化并创建对象栈,经过ModelDriven和Params拦截器时,分别往值栈中封装对象和封装参数,分别封装到相应的地方,此时数据中心中有就有了数据。
        以上均是拦截器为我们做的工作,我们只需写Action(通过ActionContext()操作Map,操作对象栈)和Jsp(通过OGNL表达式获取栈中数据)即可。
  • 相关阅读:
    文本框改造之多选下拉控件
    多附件上传控件
    Linq to Sql:更新之属性遍历法
    如何在HTML5页面中启动本地的App? 下面的方法应该可以。
    Nodejs 学习笔记-相片整理Demo(二)
    Nodejs 学习笔记-相片整理Demo(一)
    前端学习笔记一:什么是W3C?
    网页嵌入调用 全国各城市天气代码
    html页面清除缓存
    判断鼠标动作,可以给鼠标在标签不同区域的动作分别写不同的效果
  • 原文地址:https://www.cnblogs.com/wangyage/p/7299880.html
Copyright © 2020-2023  润新知