浅谈Struts2的执行流程

浅谈Struts2的执行流程_第1张图片

当客户端向服务器端发送一个action请求,该请求进入到action前会经历Struts2的多个拦截器,例如modeldriven(model拦截器)和parms(参数封装拦截器)等多个拦截器,也可以自己定义拦截器,当拦截器接收到一个action请求,就会调用create()方法创建一个值栈对象(作用范围为一次请求),再调用init()方法初始化,值栈中包含了两个对象,一个是Struts2的上下文对象contextMap和对象栈,上下文对象其实就是一个Map集合。值栈中包含了一次请求的过程中所有的参数。

Struts2参数是怎样封装到值栈中去的?
如果一个action实现了modelDriven接口,则action请求在经过modeldriven拦截器的时候会将model对象放入对象栈栈顶
浅谈Struts2的执行流程_第2张图片

例子:
public class ProductAction extends ActionSupport implements ModelDriven{
private Product model = new Product();
public Product getModel() {
return model;
}
}

经过modeldriven拦截器拦截器的时候会先判断action类是否实现了ModelDriven接口,如果实现了则会调用action类中实现的getModel方法,返回一个model对象(model对象就是要接收参数的对象,需要在类中先实例化),再放入对象栈栈顶(原本的栈顶对象是action)。当action请求经过parms(参数封装拦截器)时,parm会将参数封装到对象栈中去,如果传出来的参数有id=3,而model对象和action对象都有id这个属性,因为封装时是从栈顶开始查找的,如果找到相同的属性名,就会开始赋值,即使下面的其他对象有相同的属性名,也不会赋值,因此action对象中的id属性为null,赋值成功后再从栈顶重新找下一个属性。

注:action对象指的是action请求的那个action类的实例化对象,action对象要封装请求里面的参数需要声明和参数名相同的变量,再生成get()和set()方法。

在转发页面怎么获取Struts2传过来的参数?
action在执行的时候可以将处理好的数据放入值栈中去,当action执行完转发(重定向不行,因为值栈的作用域是一次请求)到JSP页面时可以通过OGNL表达式获取值栈中的数据,如果ognl表达式中只是写属性名,例如id,则会调用findValue()从对象栈栈顶开始找同名的属性,对象栈找不到,则会到contextMap寻找与属性名相同的key,找到后就会返回,如果在OGNL表达式中,在属性名前加上#,则表示直接从contextMap中查找,不去对象栈中查找。
在JSP页面也可以通过EL表达式获取值栈中的参数,因为struts2重写了request的getAttriture()方法(多加了一个findValue()方法),当EL开始从page域查找相同的属性名,查到request域还是找不到的话,会调用findValue()方法,从值栈中开始查找。

你可能感兴趣的:(struts2)