2.为什么使用ModelDriven拦截器?
①在我们struts2的企业级开发中,把Action和Model清晰的隔离开是很有必要的。有些Action不代表任何Model对象,它们的功能仅限于显示服务。把动作对象和model模型隔离开说明我们的模型对象不能再是动作对象的实例,那么我们如何让提交的参数映射到model对象里面去呢?那就要使用modeldriven拦截器。
②实现了modeldriven拦截器的Action类需要实现getModel()方法。当用户触发动作时,ModelDriven会调用相应Action动作对象的getModel()方法,并且把getModel()方法返回的model对象压入到值栈中的Object stack的栈顶。那么Parameter拦截器将会将页面提交的参数映射到栈顶的模型对象相应的属性当中去,如果某个参数模型对象中没有与之匹配的属性,那么将从栈顶的下一个对象中继续找与之匹配的属性并且映射到相应的属性中去。
3.那么为什么需要使用Preparable拦截器呢?
①struts2的ModelDriven的getModel()方法返回一个model对象,ModelDriven将该对象压入到栈顶中去,而这里的Preparable拦截器则负责为我们的getModel()方法准备model对象。
②实现了Preparable接口的Action类需要实现prepare()方法。但是在执行prepare()方法之前,struts尝试执行prepare[ActionMethodName]()方法,若prepare[ActionMethodName]()方法不存在,那么尝试执行下一个prepareDo[ActionMethodName]方法,如果也不存在就都不执行。最后再执行prepare()方法。这里需要说明的是,加入我们的Action中有一个处理action请求的add()方法,在Action类中添加prepareAdd()或者prepareDoAdd()方法,那么就可以通过该方法来为当前的Action准备模型对象并压入到栈顶,是的传过来的参数成功映射到model对象中去。
③我们可以通过设置PrepareInterceptor拦截器的alwaysInvokePrepare属性来告诉struts是否执行prepare()方法。默认是执行prepare()方法的。如果想要设置不执行prepare()方法,方法如下:
在struts.xml配置文件中配置
<interceptors>
<interceptor-stack name="parentStack">
<interceptor-ref name="拦截器栈名">
<param name="prepare.alwaysInvokePrepare">false</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
4.paramsPrepareParamsStack栈有什么作用呢?
①paramsPrepareParamsStack是用来设置action请求时执行拦截器的循序。从字面上理解来说,这个stack的拦截器调用拦截器的顺序是为如下:
<interceptor-stack name="paramsPrepareParamsStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>
<!--往栈顶对象中填充参数 此时栈顶对象时Action类-->
<interceptor-ref name="params"/>
<interceptor-ref name="servletConfig"/>
<!--准备model对象-->
<interceptor-ref name="prepare"/>
<interceptor-ref name=