请求发送给StrutsPrepareAndExecuteFilter;该filter判定是否是一个Struts2请求;若是,则把请求交给ActionProxy;ActionProxy创建一个ActionInvocation的实例并初始化;ActionInvocation实例调用Action的过程前后涉及到相关拦截器(Intercepter)的调用;Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果,调用结果的execute方法,渲染结果;执行各个拦截器invocation.invoke()之后的代码;把结果发送到客户端
过滤器依赖于Servlet容器,几乎对所有的请求其作用,只在容器初始化被调用一次;拦截器不依赖于Servlet,只对Action请求起作用,可以访问Action上下文(ActionContext)、值栈里的对象(ValueStack),在Action的生命周期中可以多次调用
基于MVC架构,使用OGNL快捷访问值栈中的数据,调用值栈中的对象方法。拦截器是一个Action级别的AOP,异常处理、文件上传、验证等都可以通过拦截器实现。
通过ActionContext访问域对象对应的Map对象;通过实现Aware接口使Struts2注入对应的Map对象;与ServletAPI 耦合的方式,通过ServletActionContext直接获取Servlet API对象,通过实现ServletXXXAware接口的方式使Struts2注入对应的对象
struts-default内部定义了多个拦截器和Result类型,而框架核心是通过拦截器,如:从请求中封装请求参数到action,文件上传和数据验证等。该包定义在struts-default.xml中,所以每次自动加载。
exception fileUpload i18n modelDriven params……
值栈贯穿在整个Action生命周期,保存在request域中,所以生命周期等同于requet。当框架接收到一个请求会创建ActionContext/ValueStack/Action,然后把Action存放进值栈,所以Action的实例会被OGNL访问。值栈是多实例的,因为Action是多实例的(servlet是单实例的),每个Action都有一个对应的值栈,Action对象保存在栈顶。值栈的本质是一个ArrayList,使用OGNL访问值栈内容不需要#,Struts2重写了request的getAttribute方法,所以可以使用EL直接访问值栈的内容
ActionContext 当前Action的上下文环境,属于Struts2框架的API;ServletContext和PageContext是Servlet的API
struts-default.xml中相关的配置,dispatcher chain redirect等
每个拦截器都要实现Interceptor接口,init()在拦截器被创建后立即被调用,在整个生命周期只被调用一次,可以在该方法中对相关资源进行必要的初始化。 intercept(ActionInvocation invocation)每拦截一个动作请求,该方法就会被调用一次。 destroy()该方法将在拦截器被销毁之前被调用,它在拦截器的生命周期内也只被调用一次。