首页 > 其他分享 >Struts2 中拦截器和Action的调用关系

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

时间:2023-08-27 11:04:05浏览次数:56  
标签:拦截器 String invoke Struts2 Action password public


所谓的拦截器就是指实现了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 !

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


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


补充:还可以给拦截器传递参数,进行初始化的工作。如下:

<interceptors>
	 <interceptor name="myInterceptor" class="com.suo.interceptor.MyInterceptor">
	 	<param name="suo">piao</param><!--传递一个参数-->
	 </interceptor>
</interceptors>

然后在拦截器中定义该参数的get/set方法,即可:


注意,这个参数的赋值,要早于init()方法的调用,因为初始化参数的作用,就是想在初始化的时候用到这个参数,所以要早于init()方法。



标签:拦截器,String,invoke,Struts2,Action,password,public
From: https://blog.51cto.com/u_5173797/7251447

相关文章

  • struts2中的参数传递
    这个问题其实一直很困惑我的,在写平常的jsp程序时,传递参数很容易,通过表单,request,链接等都可以传递,但是到了struts2中,在写的各个地方,都看不到任何的request或是response,不知道该怎么传递参数了,到了今天学习了struts2中的参数传递这一节,终于解开了疑惑,但是还不是很清楚,有待以后探索。......
  • Struts2中防止表单重复提交的两种方式
    防止表单重复提交,这是个很重要的知识点,而且很有用。当用户提交了一个表单,此时,地址栏显示的是处理这个表单的Action的地址,若此时刷新,则会重新发送一次表单数据,即又进行了一次提交,若这个Action是用来处理用户注册的,那么重复提交会再一次向数据库中插入之前已经插入的数据,这显然不是我......
  • struts2模型驱动
    和模型驱动的相对应的是属性驱动,虽然名字叫的挺牛的,其实很好理解。属性驱动就是在Action中,定义的是和表单中对应的一个个属性,然后有属性的get/set方法。而模型驱动就是事先定义了一个模型,即Model,将表单传递过来的数据封装成一个对象后,再传递给Action,这和Struts1的这种机制很相似。......
  • Struts2输入校验以及错误信息处理(2)——用Struts2定义好的校验框架进行校验
    Struts2的输入校验有两种方式:一种是用Action中定义的validate()方法进行校验,一种是用Struts2定义好的校验框架进行校验。前者里面的逻辑判断要自己写,而后者只需要传递相应的参数即可。不管是哪种方式,程序执行的流程都是一样的,执行流程如下:1、对表单传递过来的数据,先进行类型转换......
  • Struts2的自定义类型转换和简单的输入校验
    这里关键是对自定义类型的理解,它和8个基本数据类型的地位是一样的,只不过这个是你自己定义的类型。那么在Struts2中什么时候要用到数据类型转换呢?其实,我们一直在用,只是我们没有感觉到而已,Struts2对8个基本数据类型以及Date、String等常见类型,会自动的用内建的类型转换器进行转换,这个......
  • Struts2输入校验以及错误信息处理(1)——用Action中定义的validate()方法进行校验
    Struts2的输入校验有两种方式:一种是用Action中定义的validate()方法进行校验,一种是用Struts2定义好的校验框架进行校验。前者里面的逻辑判断要自己写,而后者只需要传递相应的参数即可。不管是哪种方式,程序执行的流程都是一样的,执行流程如下:1、对表单传递过来的数据,先进行类型转换2、......
  • struts2文件上传
    上传文件其实分为两个步骤:首先,将客户端传递过来的文件保存到struts.multipart.saveDir键所指定的目录下,如果没有指定,那么就保存到javax.servlet.context.tempdir环境变量所指定的目录下,然后,Action中所定义的成员变量file,实际指向的是临时目录中的临时文件,在服务器通过IO的方式,将临......
  • struts2异常处理
    Struts2中的异常处理有两种形式:一种是局部异常处理,一种是全局异常处理在struts.xml中的package下有两个这样的标签:<global-exception-mappings>和<global-results>,前者指定异常处理的类,后者是异常处理结果,通常指定一个显示异常信息的页面。而在action中,也有类似全局的异常处理,<exce......
  • 利用GitHub 的Actions自动同步gitee仓库,并Gitee Pages 自动部署项目
    Gitee同步GitHub仓库GitHub有时候访问速度慢,加载不了图片等问题。过程记录GitHub的Actions会处理.github下的工作流文件夹workflows。只要在g项目根目录下创建.github/workflows/,在这个文件夹里再创建Sync.yml文件,填入以下代码。当产生push操作就会自动同步gitee<divid="......
  • TransactionScope
     usingSystem.Transactions;using(TransactionScopescope=newTransactionScope(TransactionScopeOption.Required,newTransactionOptions{IsolationLevel=Syste......