2018年05月16日 15:44:20 公子尧 阅读数:277
1. 聊一下你对OGNL表达式的了解以及OGNL三要素的了解
OGNL是Object-Graph Navigation Language(对象图导航语言(所谓的对象图导航语言指的就是通过 "放置到OgnlContext中的名字.属性名字" 的方式去获取对应对象的属性值))的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
1.表达式(Expression)是整个OGNL的核心内容,所有的OGNL操作都是针对表达式解析后进行的。通过表达式来告诉OGNL操作到底要干些什么。因此,表达式其实是一个带有语法含义的字符串,整个字符串将规定操作的类型和内容。OGNL表达式支持大量的表达式,如“链式访问对象”、表达式计算、甚至还支持Lambda表达式。
2.OGNL的Root对象可以理解为OGNL的操作对象。当我们指定了一个表达式的时候,我们需要指定这个表达式针对的是哪个具体的对象。而这个具体的对象就是Root对象,这就意味着,如果有一个OGNL表达式,那么我们需要针对Root对象来进行OGNL表达式的计算并且返回结果。
3.有个Root对象和表达式,我们就可以使用OGNL进行简单的操作了,如对Root对象的赋值与取值操作。但是,实际上在OGNL的内部,所有的操作都会在一个特定的数据环境中运行。这个数据环境就是上下文环境(Context)。OGNL的上下文环境是一个Map结构,称之为OgnlContext。Root对象也会被添加到上下文环境当中去。
2.谈一谈你对ValueStack的了解
①Struts2将XWork对Ognl的扩展这一套机制封装起来,这个对象叫ValueStack。ValueStack实际上就是一个容器。它由Struts框架创建,当前端页面如jsp发送一个请求时,Struts的默认拦截器会将请求中的数据进行封装,并入ValueStack的栈顶。----百度百科
②获取ValueStack的三种方式:(2和3可以算一种,通过request获取)
1.ValueStack valueStack = ActionContext.getContext().getValueStack();
2.ValueStack valueStack = ServletActionContext.getValueStack(ServletActionContext.getRequest())
3.ValueStack valueStack = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
③.ValueStack贯穿整个action的生命周期,每一个action实例都拥有一个ValueStack对象,其中保存了当前action对象和其他相关对象.
④struts2把ValueStack对象保存在名为:struts.valueStack的request域中.即ValueStack作用域为request.当action创建的时候,ValueStack就创建了,action被销毁的时候,ValueStack就销毁了
⑤ValueStack中的数据分两部分存放:root(栈结构,CompoundRoot)和context(map形式,OgnlContext)
3.如何向ValueStack中存数据以及取数据?
要在ValueStack中存取数据,先要获得ValueStack
第一种方式:可以直接通过request对象来获取.
第二种方式:使用ActionContext来获取
set方法存数据:
在页面取set方法存的数据:
使用push方法存数据
在页面取push方法存的数据
4. 在OGNL表达式中如何去使用#、%和$这三个符号
#号:它是从非root中获取数据
%用于强制是否要解析ognl表达式,%提供一个ognl表达式运行环境
$它主要是用于配置文件中获取valueStack中数据
5. 拦截器的生命周期
1)当我们启动服务器时,就已经创建了自定义拦截栈中所有拦截器的对象(如果自己未引用自定义拦截器栈,则执行默认的拦截器栈),并且所有对象都执行了初始化方法init().
2)当用户访问action时,首先是创建Action示例,此时并没有马上执行action对应的业务逻辑方法execute(),而是执行了拦截器中的业务处理方法中invocation.invoke()这行代码之前的代码(包括自己这行代码).invocation.invoke()相当于servlet编程中过滤器的核心业务方法中的chain.doFilter().紧接着,就是先去执行Action中的业务逻辑方法execute(),当执行完execute()之后才会去继续执行拦截器业务处理方法中的invocation.invoke()之后的代码直到方法结束.
3)当服务器关闭,拦截器才会销毁
简单点说就是:
·启动服务器时候,申明在配置文件的拦截器,被初始化,调用init方法
·当有请求访问拦截器作用的action时,先创建action对象,
·执行该拦截器的intercepot方法拦截。在action目标方法 invocation.invoke()执行前后,写相应的业务逻辑。
·当服务器停止时,拦截器对象才被销毁
6. 拦截器的执行流程