struts2 知识点总结2

  1. servlet和action的区别
  1. servlet在第一次访问时被创建,并创建一次(单例)
  2. action也是在访问时创建,但会创建多次(每次都是一个新的action实例)
  3. 在action中保存数据的值栈对象也会随之而产生多个
  1. OGNL概述(Object-Graph Navigation Language)
    1. OGNL的特点
  1. 表达式语言,比EL表达式更为强大
  2. 是独立的体系,不属于struts2

  1. 存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能
  2. 配合struts2的标签操作值栈数据(大有取代el的用意)
  3. 只能在jsp页面中使用

 

    1. OGNL的使用
  1. 导入jar包(struts2中已经存在)

  1. 引入struts2标签库

  1. 调用字符串的方法:

 

  1. 值栈(valueStack)
    1. 概念

struts2中本身提供的一种数据操作的机制,类似之前servlet的域对象(域对象依然可以使用),它并不是用来替换域对象的,值栈可以和域操作同时存在互不影响(其实,值栈和域对象是有一定联系的),给我们操作数据提供了一种更适合sturts2的选择而已

    1. 存储方式

值栈在每一个Action中都独立存在一份值栈对象

    1. 获取值栈对象
  1. 通过ActionContext,调用getValueStack() 方法
  2. 通过ServletActionContext,调用getValueStack(request)方法

两种方法返回的对象是相同的

每个action中存在多少个值栈对象?如何验证

栈的结构(栈顶、栈底,push)

先入后出(FILO)

栈的典型应用:汉诺塔

拓展阅读: “在java中栈的操作实现”,通过数组方式,列表的实现方式,map的实现方式

 

    1. 值栈的内部结构

root(list) 和 context(map)

 

context中的结构:

 

root的结构(一般都是操作root):

 

    1. s:debug 标签

通过s:debug标签调试程序(上线的程序不能使用),查看值栈中的数据情况

在struts中添加常量(开启调试模式,老版本不需要):

<constant name="struts.devMode" value="true" />

在jsp页面中添加debug标签

打开页面后:

点击链接:

值栈中存在Action的引用(通过root既能观察到,目的是方便取值)

 

 

 

 

 

    1. 向值栈中存放数据

三种方式

  1. 通过值栈对象调用set方式(以map的方式添加)
  2. 通过值栈对象调用push方式

  1. 在action中声明变量,定义变量的get方法(主要)

通过观察上述三种方式,数据存放的形式和位置,分析优劣

  1. 存放字符串
  2. 向值栈中存放对象
  3. 向值栈中存放集合

声明时可以不赋初值,但返回之前一定要赋值

 

    1. 从值栈中获取数据

思路: 利用s:property标签,value中指定字符串/对象/集合的名称

  1. 从值栈中获取字符串

  1. 从值栈中获取对象

  1. 向从值栈中获取集合

获取集合操作中,使用下标方式

还可以利用s:iterator 执行遍历集合的操作

或者

或者使用#号(原因是,list中的数据在struts2被优化后,存放在了context中,#就是用来标识这种特殊位置的)

 

  1. 获取值域对象通过set方法生成的值

思路:set方法生成的是Map,所以直接通过key获取value

 

 

  1. 获取值域对象通过push方法生成的值

思路:值栈中会把存入的数据放在一个叫做top的数组中,再根据入栈的顺序,采用下标的方式来获取,但,此处有一个特殊的语法: [0].top

 

使用jstl标签结合el表达式,也可以获取值栈传递的数据

原因是struts2在过滤器中,对于request进行了增强操作:判断request域对象中是否有目标值,如果有则获取该值,如果没有,则判断值域中是否有,有则传递给域对象

简单来说就是,request通过增强,获取了值域中的数据,从而让el表达式能够获取

 

 

 

    1. ognl中 # 和 %的使用:
  1. #用于获取值栈中context里的数据

如果想要访问reqeust作用域中的数据,可以选择采用ognl表达式

格式: #对象

例如:context中就存放了request对象,通过ognl获取request中的数据:

 

  1. %用于在ognl标签中使用表单标签时,识别数据的方法(非重点)

格式: %{ name}  %{#request.request}

 

  1. 关于拦截器:(复刻)
  1. 概念:动态拦截Action的对象,提供了一种机制,使得开发者在定义的action执行前后加执行的代码;封装大量的功能的组件;也可以在一个action执行前组织其执行,也就是说它提供了一种可以提取action中的重复代码,统一管理和执行的方式
  2. 大量的拦截器完成不同的功能
  3. 拦截器链,即拦截器栈(Interceptor chain->Interceptor Stack),将拦截器按一定顺序链接成一条链,当访问到被拦截的方法或字段时,拦截器栈中的拦截器就会按顺序执行其中定义的拦截器

  1. 和过滤器的区别:
  1. 过滤器是servlet中你的规范,任何web项目都可以使用
  2. 拦截器是struts2框架中的模块
  3. 过滤器可以过滤任何内容,拦截器只能拦截目标action
  1. 通常情况下,struts2中会执行一组默认的拦截器
  2. 拦截器的位置:

 =>  =>

拦截器的加载机制: 在Action对象创建之后,方法执行之前执行拦截器操作

  1. 拦截器底层原理
  1. AOP思想(面向切面编程,约定大于配置,spring的重点)

在不修改源码的基础上对已有的方法进行动态增强

在struts2中,拦截器就是对Action进行增强(将复刻代码提出来,放在拦截器中统一管理和执行)

  1. 责任链模式(动态代理)

在action方法执行之前执行默认拦截器,执行过程使用AOP思想(action没有直接调用拦截器的方法,而是使用配置文件方式进行操作)

在执行多个默认的拦截器的时候,使用责任链模式(拦截器1执行完毕之后->放行->执行拦截器2->拦截器2执行完毕后放行->执行拦截器3->拦截器3执行完毕放行->action)

  1. 拦截器时序图

https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1543776485538&di=feaaac5c2976e0dcd4d03685891977ee&imgtype=jpg&src=http%3A%2F%2Fimg1.imgtn.bdimg.com%2Fit%2Fu%3D1565509691%2C2474085951%26fm%3D214%26gp%3D0.jpg

  1. 自定义拦截器
  1. 目的:通过自定义拦截器,补充系统默认拦截器中不具备的功能
  2. 常用方法:
  1. 实现Interceptor接口,

  1. 继承AbstractInterceptor

  1. 继承MethodFilterInterceptor
  1. 拦截器结构概述,

以MethodFilterInterceptor为例

它不仅继承了AbstractInterceptor,还可以指定不拦截的方法

其中的核心为doIntercept(ActionInvocation actionInvocation)

放行即通过actionInvocation对象执行invoke方法(注意,该方法并不是反射)

当不放行而要拦截并引导到方法的返回值name即可(拦截器最终会回到action,返回name即在通知action执行方法的哪一个)

拦截器放行之后的情况

拦截器返回为null的情况

  1. 在action中配置拦截器

在被拦截的action所在package标签中声明拦截器(interceptors/interceptor标签)

在action中使用声明的拦截器(interceptor-ref标签)

  1. 拦截器的返回值

拦截器返回的是action执行的方法的返回值,那么,如果拦截器同时存在放行和return呢?

jsp页面在拦截器执行完毕后才会显示,所以,执行到放行的时候,jsp的内容是暂存在缓冲区的,不管最后return的是什么,都显示的是缓冲区的内容

  1. 添加其他默认拦截器

注意,package中如果有其它标签,interceptors必须在最前

自定义拦截器会让默认拦截器失效,手动添加一次,引用defaultStack即可),根据实际情况,如果不需要使用默认中的功能,则不需配置

  1. 设置拦截器栈:

指定interceptor-stack

指定 default-interceptor-ref

action 改为引用拦截器栈

  1. 不拦截某个action

拦截器会对action中所有方法都进行拦截,需要对指定的方法不进行拦截(在interceptor-ref中进行配置),使用param标签并配置不拦截的方法名称(不是name名称),多个不拦截的方法可以用,隔开

  1. 多个拦截器执行(拦截器链,“层层保安”的机制,执行顺序由引用顺序决定,与声明顺序无关)
  2. 多个Action使用相同的拦截器
  1. 拦截器之间的关系

https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1543776348974&di=00384176e2c017510ba739e2988bb714&imgtype=0&src=http%3A%2F%2Fimage.bubuko.com%2Finfo%2F201703%2F20180110225420135171.png

 

  1. 使用注解配置拦截器
  1. 要想使用注解,就必须使用jar包: struts2-convention-plugin-2.5.18.jar

 

 


 

 


 

猜你喜欢

转载自blog.csdn.net/hepan_/article/details/84782704
今日推荐