拦截器中获取getModel()报null

来源:互联网 发布:数控车床编程基础视频 编辑:程序博客网 时间:2024/05/17 03:36
遇到一个问题,在拦截器中获取action中的注入到模型中的数据取不到。

        页面:

        点击添加后界面报错
                   

        AddLogInterceptor:(拦截器类)



        后台输出:

        
        看下项目配置:

        
struts.xml:


        StudentAction:


        这里主要是拦截器的问题,项目一发布运行,Struts里面的ConfigruationManager 配置管理中心就会加载Struts.xml,Action是用了代理模式,其中的ActionProxy就会问配置管理中心,我要调用哪个action。ActionProxy会拿到对应的action,及相关的拦截器,以及所有的result信息,这时会创建ActionInvocation对象。在ActionInvocation里面呢,会顺序的执行拦截器链。

        这里,先执行了
defaultStack,然后呢,执行了hello拦截器--》addLog拦截器。 报错的位置呢,在add(student)那里,这里可以判定student应该被我的ModelDriven注入了,但是为什么没有呢??

         原因:
 在defaultStack的拦截器
栈,里面


里面加入了modelDriven这个拦截器,其中做了一步操作。下面我们看下ModelDrivenInterceptor的核心源码

说明:ModelDrivenInterceptor是默认的拦截器链(struts-default)的一部分。

当一个请求经过ModelDrivenInterceptor的时候,它会判断当前要调用的Action对象是否实现了ModelDriven接口,如果实现了这个接口,则调用getModel()方法,并把返回值压入ValueStack。
// 核心代码:
public class ModelDrivenInterceptor extends AbstractInterceptor {
        @Override 
        public String intercept(ActionInvocation invocation) throws Exception { 
                Object action = invocation.getAction();// 如果action实现了ModelDriven接口,则执行下面的代码
                if (action instanceof ModelDriven) {// 把action强转为ModelDriven 
                        ModelDriven modelDriven = (ModelDriven) action;// 获得值栈 
                        ValueStack stack = invocation.getStack();// 获得model 
                        Object model = modelDriven.getModel(); 
                        if (model != null) {// 把获得的model压入ValueStack的对象栈(Value Stack Contents)
                                stack.push(model); 
                        }
                } return invocation.invoke(); 
        }
} 

发现其中有一布就执行了getModel();将值注入到Student这个模型中了。 然后在执行后面的拦截器。

AddLogInterceptor这个类中呢,又调用了一次getModel().在StudentAction中又实例化了一次Student对象。 所以此时的student这个对象为null。

拦截器执行完之后,才会执行action(具体执行流程请看另一篇日志),所以在add()方法里面会报null。
在student.getName()也为null。

解决方案:
        将 
StudentAction作如下修改。
         

此时,不管你在调用多少次getModel(),都会返回这次请求的这个student对象。

在web开发时,需要注意的是,这个是单例还是多例的呢,如果是单例,设置全部变量就不安全了,当多用户访问时就会出问题。
但是struts2里面的action都是多例的,所以这样子写是没有问题的。(拦截器是单例的)。 

0 0
原创粉丝点击