1.Params拦截器:
- 作用:Parameters拦截器将把表单字段映射到ValueStack栈的栈顶对象的各个属性中,
- 注意:如果某个字段在栈顶对象中没有对应的属性,则Params拦截器将尝试在ValueStack中的下一个对象
2.ModelDriven拦截器
- 作用:
- Struts2作为企业级的前端应用程序,将Action和Model隔离开是很有必要的
- 有些Action类并不代表任何Model对象,它们的存在仅仅提供显示服务
- 流程:
- 先会执行ModelDrivenInterceptor的Intercept方法
- 执行
- ParametersInterceptor的intercept方法:把请求参数的值赋给栈顶对象对应的属性
- 注意:getModel方法不提供以下实现,的确会返回一个Employee对象到值栈的栈顶,但是当前action的employee确是null
3.paramsPrepareParamsStack拦截器栈:
- 问题:
- Struts2表单回显时,从值栈栈顶开始查找匹配的属性,若找到就添加到value属性中
- 若想将Employee对象压入到值栈栈顶,未使用
而是直接使用
此时的栈顶对象除了employeeId之外全部为null - 此时,不能够进行表单的回显,因为经过重写赋值的employee对象以及不是栈顶对象
- 可以手动将Employee对象放入到值栈栈顶,但是值栈中会存在两个Employee对象,造成冗余
- 解决方法:
- 因为Action类实现了ModelDriven接口,所以我们可以在getModel方法中判断是Edit还是Create
- 若为Edit则
- 若为Create则
- 此处我们可以根employeeId进行判断,若id为null,则是Create否则是Edit
- 但是,使用employeeId来判断则需要在ModelDriven拦截器之前使用一个params拦截器
- 而这个可以使用paramsPrepareParams拦截器栈来实现,因为默认的拦截器栈中ModelDriven之前没有params
- 缺点:
- 在执行删除操作的时候,getModel方法会从数据库中加载一个对象,浪费资源
- 执行查询全部信息是也会new 一个新的对象出来,造成浪费
- 流程:
- params拦截器首先给action中的相关参数赋值
- prapare拦截器首先调用prapare方法,给方法中会根据参数(如id)去调用业务逻辑,设置model对象
- modelDriven拦截器将model对象压入到value stack,这里的model对象就是在prapare中创建的
- params拦截器再将参数赋值给model对象
- action业务逻辑执行
3.preparable拦截器:
- 作用:
- struts2中的modelDriven拦截器负责把Action类以外的一个对象压入到值栈栈顶
- 而prepare拦截器负责准备为getModel()方法准备model
- 一般prepare拦截器是和modelDriven拦截器一起使用的
- PrepareInterceptor 运行流程(源码解析):
- PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes)方法:
- PrefixMethodInvocationUtil.getPrefixedMethod方法:
- 总结:
- 若Action实现了Prepareble接口,则struts将尝试执行prepare[ActionMethodName]方法,若prepare[ActionMethodName]不存在,则会尝试执行prepareDo[ActionMethodName]方法
- 若PrepareInterceptor的alwaysInvokePrepare属性为false,则struts将不会调用实现了Prepareble接口的Action的prepare方法
- 解决getModel方法造成的浪费:
- 可以为每一个ActionMethod准备prepare[ActionMethodName]方法,而抛弃原先的prepare方法
- 将PrepareInterceptor的alwaysInvokePrepare属性设置为false,以避免Struts框架再调用prepare方法
- 如何在配置文件中为拦截器栈的属性赋值