现在的位置: 首页 > 综合 > 正文

Struts2 中拦截器和Action的调用关系

2018年01月27日 ⁄ 综合 ⁄ 共 3702字 ⁄ 字号 评论关闭

此文章参考自:http://wenku.baidu.com/view/eca714ccad51f01dc281f1d2.html

    所谓的拦截器就是指实现了Interceptor接口的类,该接口中定义了三个方法:init(),destroy(),intercept()。

    init()用于在服务器启动的时候,初始化这个拦截器。destroy()用于清理分配给拦截器的资源,intercept()是用来起拦截作用的,这个方法还有一个ActionInvocation类型的参数invocation,并且返回一个字符串。ActionInvocation类中有一个方法,是invoke(),这个方法很重要,它的作用是首先判断一下有没有其他的拦截器了,如果有,则继续进入下一个拦截器,如果没有那么就进入Action中执行业务逻辑。
            intercept()方法的执行过程也很特殊,在invoke()函数之前的代码先执行,执行到invoke()时,判断一下,进入下一个拦截器,或是进行Action的业务处理,等到执行完所有请求转发的Action时,会再回到intercept()方法,继续执行invoke()后面的内容。

    注意上面红颜色的部分,为什么是执行完所有的请求转发的Action呢?这是因为执行完当前的Action,可能会请求转发(服务器内部跳转)或是重定向到另一个Action中或是结果页面,若是重定向的话,那么就不是在一个请求过程中了,就会重新发一次请求,请求另一个Action,因为一个拦截器只会对一个特定的Action起作用,所以重定向,就完全是另一次请求过程了。然而在拦截器中,若是重定向到另一个Action的话,那么当前的Action就算完成了它的业务逻辑,就会返回执行invoke()方法之后的内容,然后,再进行另一次请求过程。如果是请求转发的话,那么Action之间是在一个请求过程中,等到所有的请求转发的Action执行完之后,才会去执行invoke()后面的内容。

    下面,举两个例子对比一下:
    有一个jsp页面,两个Action:Action1和Action2

    第一次:Action1和Action2之间是请求转发关系
    第二次:Action1和Action2之间是重定向关系

Login.jsp: 

<form action="/struts2/test/action1" method="post"> 
        姓名:<input type="text" name="username"/><br/> 
        密码:<input type="password" name="password"/><br/> 
        <input type="submit" value="提交"/> 
</form>

拦截器:MyInterceptor.java: 

package com.suo.interceptor; 
  
import com.opensymphony.xwork2.ActionInvocation; 
import com.opensymphony.xwork2.interceptor.Interceptor; 
  
public class MyInterceptor implements Interceptor { 
  
    @Override  
    public void destroy() { 
        // TODO Auto-generated method stub  
        System.out.println("destroy invoke !"); 
    }  
  
    @Override  
    public void init() { 
        // TODO Auto-generated method stub  
        System.out.println("init invoke !"); 
    }  
  
    @Override  
    public String intercept(ActionInvocation invocation) throws Exception { 
        System.out.println("before invoke !");  
          
        String result=invocation.invoke();  
          
        System.out.println("after invoke !");  
          
        return result; 
    }  
  
}  


Action1.java:  

package com.suo.actions; 
  
import com.opensymphony.xwork2.ActionSupport; 
  
public class Action1 extends ActionSupport { 
      
    private String username; 
    private String password; 
      
    public String getUsername() { 
        return username; 
    }  
    public void setUsername(String username) { 
        this.username = username; 
    }  
    public String getPassword() { 
        return password; 
    }  
    public void setPassword(String password) { 
        this.password = password; 
    }  
      
    public String execute() 
    {  
        System.out.println("action1 invoke !");  
        return SUCCESS; 
    }  
}

Action2.java: 

package com.suo.actions; 
  
import com.opensymphony.xwork2.ActionSupport; 
  
public class Action2 extends ActionSupport { 
      
    private String username; 
    private String password; 
      
    public String getUsername() { 
        return username; 
    }  
    public void setUsername(String username) { 
        this.username = username; 
    }  
    public String getPassword() { 
        return password; 
    }  
    public void setPassword(String password) { 
        this.password = password; 
    }  
  
    public String execute() 
    {  
        System.out.println("action2 invoke !");   
        return SUCCESS; 
    }  
}


在struts.xml中配置拦截器:

<interceptors> 
    <interceptor name="myInterceptor" class="com.suo.interceptor.MyInterceptor"></interceptor> 
</interceptors>

在action中,引用这个拦截器,注意,这里Action之间是请求转发的关系

<action name="action1" class="com.suo.actions.Action1"> 
     <result name="success" type="chain"><!--注意这里是请求转发类型--> 
        <param name="actionName">action2</param> 
     </result> 
     <interceptor-ref name="myInterceptor"></interceptor-ref><!--这里是引用自定义的拦截器--> 
     <interceptor-ref name="defaultStack"></interceptor-ref> 
<!--注意,每一个action都有一个默认的拦截器,如果指定了自定义的拦截器,那么默认的拦截器就失去作用了,所以这里要再加上默认的拦截器--> 
</action> 
          
<action name="action2" class="com.suo.actions.Action2"> 
     <result name="success">/WEB-INF/result/action.jsp</result> 
</action>

启动服务器,可以看到输出的结果是:

        before invoke !  
        action1 invoke !  
        action2 invoke !  
        after invoke ! 

  说明程序先进入拦截器,执行到invocation.invoke() 方法时,进入Action进行业务处理,由于两个action之间是通过请求转发进行跳转,所以属于一次请求,待action业务处理结束之后,返回拦截其中继续执行。


  若是将Action间的类型换成redirectAction,那么输出的结果是:

   before invoke !  
    action1 invoke !  
    after invoke !  
    action2 invoke !

  当两个action之间通过客户端重定向跳转,发生跳转会产生一次新的请求,因此,在Action1执行结束,进行跳转时,表示第一次请求已经结束,会返回到拦截其中执行代码,拦截器代码执行完毕后,刚才的跳转会作为新的请求执行,即执行Action2中的代码

抱歉!评论已关闭.