框架之struts2(二)

一.Struts2的模型驱动
    1.编写要求:
        *动作类必须实现ModelDriven接口,并提供抽象方法实现
        *必须我们自己实例化模型对象
  
  
  1. 动作类:
  2. public class CustomerAction extends ActionSupport
  3. implements ModelDriven<CstCustomer>{
  4. private ICustomerService customerService =new CustomerServiceImpl();
  5. private CstCustomer customer =new CstCustomer();
  6. public CstCustomer getModel(){
  7. return customer;
  8. }
  9. /**
  10. * 添加客户
  11. */
  12. public String addCustomer(){
  13. //保存操作
  14. customerService.saveCustomer(customer);
  15. return"addCustomer";
  16. }
  17. /**
  18. * 添加客户页面的展示
  19. */
  20. public String addCustomerUI(){
  21. //1.获取客户来源的列表
  22. List<CstBaseDict> basedicts = customerService.findAllCustomerSource();
  23. //2.把查询出来的结果存入请求域中
  24. HttpServletRequest request =ServletActionContext.getRequest();
  25. request.setAttribute("baseDicts",basedicts);
  26. return"addCustomerUI";
  27. }
  28. }
二.OGNL表达式和OGNL上下文(ContextMap)
    1.OGNL:Object-Graph Navigation Language(对象图导航语言),它是一种功能强大的表达式语言,
        它比EL功能强大的多:
            EL只能从域对象中获取值,EL表达式只能获取数据
            OGNL: *支持对象的普通方法的调用,使用对象.方法名
                        *支持访问静态属性,使用@包名.类名@属性名称
                        *支持静态方法的调用,使用@包名.类名@方法名称
               注意:静态方法调用需要在配置文件中单独开启,未开启时不能使用(struts.ognl.allowStaticMethodAccess)
                        *支持赋值操作
                        *支持访问OGNL上下文对象(OGNLContext)
                        *支持操作集合对象(list和map)
  
  
  1. <%@ page language="java"import="java.util.*" pageEncoding="UTF-8"%>
  2. <%@ taglib uri="/struts-tags" prefix="s"%>
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  4. <html>
  5. <head>
  6. <title>OGNL的入门</title>
  7. </head>
  8. <body>
  9. <%--1.要想使用OGNL,必须在struts2的标签中配置
  10. 2.OGNL支持普通的方法调用
  11. <s:property value=""/>它就相当于把标签中value属性的取值输出到浏览器上
  12. value属性的取值是一个OGNL表达式,注意不是一个字符串
  13. 如果要想让OGNL表达式就当成普通的字符串来处理的话,需要在外面套上单引号
  14. --%>
  15. <s:property value="OGNL-Expression"/><br/>
  16. <s:property value="'OGNL-Expression'"/><br/><%--由于套上了单引号,所以value的取值就变成了一个普通的字符串--%>
  17. <hr/>
  18. <%--3.OGNL访问静态属性
  19. 使用的是@包名.类名@静态属性名称
  20. --%>
  21. <s:property value="@java.lang.Integer@MAX_VALUE"/>
  22. <hr/>
  23. <%--4.普通方法调用--%>
  24. <s:property value="'OGNL-Expression'.length()"/>
  25. <s:property value="'OGNL-Expression'.substring(0,5)"/>
  26. <hr/>
  27. <%--5.静态方法调用:
  28. 注意要想访问静态方法,必须开启配置:struts.ognl.allowStaticMethodAccess
  29. --%>
  30. <s:property value="@java.lang.Math@random()"/>
  31. <hr/>
  32. <%--6.使用OGNL操作List
  33. 注意:使用struts2的表单标签,必须提供name属性
  34. s:radio标签是创建了一组单选按钮
  35. list属性的取值是一个OGNL表达式,把大括号内的每个元素都当成list中的元素。
  36. --%>
  37. <s:radio list="{'男','女'}" name="gender" label="性别"></s:radio>
  38. <hr/>
  39. <%--7.使用OGNL操作Map
  40. #{key:value,key:value}就相当于创建了一个map集合
  41. 无论使用struts2的表单哪个标签,最终在浏览器上能解析的都是html标签。
  42. html标签的value取值是mapkey,显示浏览器上的信息是mapvalue
  43. --%>
  44. <s:radio list="#{'male':'男','female':'女'}" name="gender" label="性别"></s:radio>
  45. </body>
  46. </html>
    2.OGNL上下文(ContextMap)
        *关于动作类的生命周期:
            动作类是多例的,每次动作访问,动作类都会实例化,所以线程是安全的,
        *关于请求动作的数据存放
            在每次动作执行前,核心控制器StrutsPreparedAndExecuteFilter都会创建一个ActionContext和ValueStack对象,并且动作类是多例的,每次访问都会被创建,
            这两个对象储存了整个动作访问期间用到的数据,并且把动作绑定到了线程局部变量(ThreadLocal)上,所以线程是安全的.
    3.ContextMap的组成
             

ContextMap中存放的主要内容

Key

Value

说明

ValueStack (root)

java.util.List

它是一个list。key不是ValueStack,而是:

com.opensymphony.xwork2.util.ValueStack.ValueStack 。但是我们不用!

application

java.util.Map<String,Object>

ServletContext中的所有属性。

session

java.util.Map<String,Object>

HttpSession中的所有属性。

request

java.util.Map<String,Object>

ServletRequest中的所有属性。

parameters

java.util.Map

参数

attr

java.util.Map

把页面、请求、会话、应用范围内的所有属性放到一起。按照从小到大的范围搜索。

    4.在jsp中查看OGNL上下文中的数据:
            <s:debug></debug>
    5.ContextMap与ActionContext和ValueStack之间的关系
        *ContextMap:它是OGNL上下文对象,是一个MAP结构,里面包含了web阶段的三个域对象中的数据(请求域,会话域和应用域),以及一个ValueStack(值栈)中的数据
        *ValueStack:它是一个list结构,里面存入的都是对象,实现了栈的特点,先进后出,它是OGNL上下文的一部分
        *ActionContext:它是一个工具类,是struts2为了方便我们快速获取和操作三个域以及值栈所提供的一个类
    6.获取map中的数据:
        *获取ContextMap中的数据,使用<s:property value=""/>
        *获取ActionContext中的数据,使用#key的方式
    7.ValueStack中的存取操作
        *获取ValueStack和压栈操作:
            ActionContext context = ActionContext.getContext();
            ValueStack vs = context.getValueStack()
            vs.push(Object);
        *获取ValueStack中的值:
            借助<s:property value=""/>,使用OGNL表达式,只能根据property name来获取ValueStack中的property value,不能使用#号
            获取ValueStack中指定位置元素的属性:  [x].propertyName,x是从0开始
    8.原来EL表达式从四大域对象中依次查找属性,搜索的范围是由小到大
            pageScope --> requestScope --> sessionScope --> applicationScope
    9.OGNL表达式查找属性顺序:
            pageScope --> requestScope --> ValueStack --> contextMap --> sessionScope --> applicationScope
三.模型驱动再分析
    由于我们的动作类实现了ModelDriven接口,并且在执行动作类之前会有一个默认的拦截器栈DefaultStack为我们工作,里面有一个拦截器名称是:ModelDriven。

    它判断了当前的动作类是否是ModelDriven类型,如果是的话,转成该类型,并且调用了getMode()方法,这时其实调用的是我们动作类重写接口的方法。

    拦截器判断了得到的模型是否为null,如果不为null,进行压栈。(而并没有判断为null的情况,这也就是我们为什么要自己实例化模型的原因)。

       接下来,就是JSP页面上form表单了,它的input元素中name属性取值全都变成了OGNL表达式,那么就会从栈顶逐个元素往下查找属性名称,并通过params拦截器给属性赋值。由于我们的模型被拦截器压栈了,所以模型跑栈顶去了,这也就是params拦截器能给我们封装成功的原因。

四.struts2的拦截器
    1.拦截器:interceptor,它是struts2的一个重要组成部分,是针对我们访问action进行拦截
    2.Filter与Interceptor之间的区别:
        *过滤器拦截的是请求级别
        *拦截器拦截的是对action的访问,拦截器不能拦截jsp,拦截是对action的访问,拦截到action内部所指向的方法
        *Filter是javaweb三大组件之一(另外两个:servlet和listener)
        *Interceptor是struts2框架的
    3.拦截器的重要性:struts2中的很多功能是由拦截器完成的,它是对我们动作方法的增强,是AOP编程思想的一种应用方式
    4.默认的拦截器栈:是一个叫defaultStack的拦截器栈,它是struts-default.xml中定义的
    5.自定义拦截器:
           *编写步骤:
                *编写一个普通的类,继承自AbstractInterceptor,实现里面的抽象方法.
                *配置拦截器,声明拦截器,然后使用拦截器      
                声明:<interceptors><interceptor name="" class=""/>      使用:<interceptor-ref name="">
                注意:当我们声明了拦截器,那么默认的拦截器就失效了
        *拦截器放行:invocation.invoke(),方法的返回值其实就是动作类中动作方法的返回值
        *多个拦截器的执行顺序:与声明顺序无关,与使用顺序有关
     6.其他标签
            *<interceptor-stack name=""><interceptor-ref name=""></interceptor-stack>:定义拦截器栈
            *<default-intercepor-ref name=""> :定义默认的拦截器栈
            *<global-results>  : 定义全局的结果变量

五.OGNL中特殊符号的使用
    #

    a、取ActionContext中key时使用

            例如<s:property value="#name" />

    b、OGNL中创建Map对象时使用,例如:<s:radio list="#{'male':'男','female':'女'}" />

    $

    a、在JSP中使用EL表达式时使用,例如${name}

    b、在xml配置文件中,编写OGNL表达式时使用。

    %

    在struts2中,有些标签的value属性取值就是一个OGNL表达式

        例如<s:property value="OGNL Expression" />

    还有一部分标签,value属性的取值就是普通字符串

        例如<s:textfield value="username"/>

    如果想把一个普通的字符串强制看成时OGNL,就需要使用%{}把字符串套起来。

        例如<s:textfield value="%{username}"/>。

              当然在<s:property value="%{OGNL Expression}" />也可以使用,但不会这么用。






















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿人小郑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值