Struts2学习笔记四(拦截器与注解)

  • 这是学习过程的一些记录,可能会有些地方出错,仅供参考

拦截器的介绍

在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者在定义的action执行的前后加入执行的代码,也可以在一个action执行前阻止其执行。也就是说它提供了一种可以提取action中可重代码,统一管理和执行的方式。

  • 拦截器与Fliter过滤器的区别
  1. 过滤器是所有web开发都能够使用的技术,也就是说filter是web开发中的一种规范,但是拦截器Interceptor是Struts2的一门技术,只有在Struts2中可以使用。
  2. 在过滤器中,filter能够过滤所有的资源,包括servlet、jsp、html等资源,但是因为拦截器是属于Struts2的技术,所以也就只能拦截Struts2所特有的资源,也就是Action,拦截器只对后缀为action的进行拦截。
  • 拦截器的作用

在Struts2中,拦截器可以说是Struts2的核心技术,我们之所以不用关心编码问题,参数封装问题,这都是因为拦截器都帮我们做好了,因此我们可以只专注于业务逻辑的处理,拦截器在内部还帮我们做了许多的事情。

  • 拦截器的定义与使用
  1. 创建拦截器类的两种方式
package com.wzm.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

/*
 * 拦截器的第一种创建方式,通过实现接口Interceptor,接口是属于拦截器的最底层,需要实现其中的所有方法
 */
public class MyInterceptor implements Interceptor{
	public String intercept(ActionInvocation invocation) throws Exception {
		System.out.println("Interceptor在action之前执行了");
		//invocation.invoke()方法类似于过滤器Filter的放行chain
		//在处理完本拦截器的相应逻辑后,将请求交于下一个拦截器,如果没有就直接交于Action执行
		//其返回值为Action执行完后的返回值,这个返回值最终要到struts.xml中与result标签对比
		String str = invocation.invoke();
		System.out.println(str);
		//在Action执行完之后,其返回值还会经过拦截器,可以再进行相应逻辑处理
		System.out.println("Interceptor在action之后执行了");
		//最终将action的返回值送到struts.xml的result中对比
		return str;
	}

	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	public void init() {
		// TODO Auto-generated method stub
		
	}

}

package com.wzm.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.Interceptor;

/*
 * 拦截器的第一种创建方式,通过继承AbstractInterceptor,该类实现了Interceptor接口
 * 该类只需要我们实现intercept方法
 */
public class MyInterceptor1 extends AbstractInterceptor{
	
	public String intercept(ActionInvocation invocation) throws Exception {
		System.out.println("Interceptor1在action之前执行了");
		//invocation.invoke()方法类似于过滤器Filter的放行chain
		//在处理完本拦截器的相应逻辑后,将请求交于下一个拦截器,如果没有就直接交于Action执行
		//其返回值为Action执行完后的返回值,这个返回值最终要到struts.xml中与result标签对比
		String str = invocation.invoke();
		System.out.println(str);
		//在Action执行完之后,其返回值还会经过拦截器,可以再进行相应逻辑处理
		System.out.println("Interceptor1在action之后执行了");
		//最终将action的返回值送到struts.xml的result中对比
		return str;
	}
}

  1. 拦截器的定义与使用
<package name="test7" extends="struts-default" namespace="/">
	  	
	  	<!-- interceptors用来定义拦截器的 -->
	  	<interceptors>
	  		<!-- interceptor定义一个拦截器,name可以自己定,class为拦截器的全限定名
	  			可以有多个	interceptor
	  		 -->
	  		<interceptor name="myInterceptor" class="com.wzm.interceptor.MyInterceptor"></interceptor>
	  		<interceptor name="myInterceptor1" class="com.wzm.interceptor.MyInterceptor1"></interceptor>
	  		
	  		<!-- interceptor-stack定义一组拦截器,即将interceptor定义的拦截器包含进来
	  			interceptor-stack可以在里边包含另一组拦截器	
	  		 -->
	  		<interceptor-stack name="myInterceptorStack">
	  			<!-- 这里需要包含进Struts2中默认的一组拦截器
	  					因为struts2默认的拦截器会帮我们做很多事,例如模型驱动封装就是默认拦截器帮我们做的
	  					如果不包含进来,当我们使用这组拦截器时就只会执行我们自己定义的拦截器
	  			 -->
	  			<interceptor-ref name="defaultStack"></interceptor-ref>
	  			<!-- 自己定义的拦截器 -->
	  			<interceptor-ref name="myInterceptor"></interceptor-ref>
	  			<interceptor-ref name="myInterceptor1"></interceptor-ref>
	  		</interceptor-stack>
	  	</interceptors>
	  	
	  	<!-- 定义好拦截器要使用,这里是在全局使用拦截器,即对整个包下的action有效 -->
	  	<default-interceptor-ref name="myInterceptorStack"></default-interceptor-ref>
	  	
	  	<action name="demo8" class="com.wzm.action.ActionDemo8">
	  		<!-- 在action中使用拦截器,即该拦截器只在该action中生效
	  				同时如果全局也有使用拦截器的话,全局的会失效,以action的优先
	  		 -->
	  		<interceptor-ref name="myInterceptor"></interceptor-ref>
	  		<result>/ognl.jsp</result>
	  	</action>
	  	
	  </package>
  • 对特定方法的拦截

在之前的拦截器都是对action的所有方法进行拦截,这里实现对action的特定的方法进行拦截。

  • 创建拦截器
package com.wzm.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;


/*
 * 在创建拦截器时,不管是实现接口Interceptor还是继承父类AbstractInterceptor,
 * 这两种方式都是对action中的所有方法都拦截,也就是说不过请求过来到action的哪个方法都会先执行拦截器
 * 而这里的继承MethodFilterInterceptor类。
 * 可以实现只对访问某些方法的请求进行拦截,这个底层同样是实现了Interceptor
 */
public class MyInterceptor2 extends MethodFilterInterceptor{

	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		System.out.println("MyInterceptor2在action之前执行了");
		String string = invocation.invoke();
		System.out.println("MyInterceptor2在action只会执行了");
		return string;
	}

}

  • 拦截器的使用
<package name="test8" extends="struts-default" namespace="/">
	  	<interceptors>
	  		<interceptor name="MyInterceptor2" class="com.wzm.interceptor.MyInterceptor2">
	  		<!-- 	
	  			在定义拦截器的时候,在内部添加标签param
	  			includeMethods代表要拦截访问哪些方法的请求
	  			excludeMethods代表不拦截访问哪些方法的请求
	  			方法可以写多个,用逗号隔开
	  			<param name="includeMethods">find</param> -->
	  			<param name="excludeMethods">find</param>
	  		</interceptor>
	  	</interceptors>
	  	
	  	<action name="demo9" class="com.wzm.action.ActionDemo8" method="find">
	  		<interceptor-ref name="MyInterceptor2"></interceptor-ref>
	  	</action>
	  	
	  </package>
  • Action类
package com.wzm.action;


import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.wzm.entity.User;


public class ActionDemo8 extends ActionSupport implements ModelDriven<User>{

	//注意,当action实现ModelDriven来封装一个对象时,ModelDriven会把被封装的对象也放在Root区的栈顶
	private User user = new User();
	public User getModel() {
		return user;
	}
	@Override
	public String execute() throws Exception {
		System.out.println("execute执行");
		return null;
	}
	
	public String find() throws Exception {
		System.out.println("find执行");
		return null;
	}

	
}

Struts2注解的使用

在Struts2中同样有注解,通过使用注解可以代替struts.xml中的部分配置,要使用注解有两个条件。

  1. 要导入一个struts2解压缩包lib下的包struts2-convention-plugin-2.3.24.jar
  2. 注解只能在特定的包下使用,只有包名中包含action,actions,struts,struts2下的类才能使用注解。
  • 注解的使用
package com.wzm.action;


import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

/*
 * 注解的使用
 */

/*
 * @ParentPackage要继承的包,@Namespace命名空间
 * 	相当于
 * <package name="test8" extends="struts-default" namespace="/">
	</package>
 */
@ParentPackage("struts-default")
@Namespace("/")
public class ActionDemo9 extends ActionSupport{

	/*
	 * value:访问路径
	 * results:返回的逻辑页面
	 * 相当于
	 * <action name="demo10" class="com.wzm.action.ActionDemo9" method="execute">
	 * 		<result name="success" type="dispatcher">/ognl.jsp</result>
	 * 		<result name="login" type="redirect">/ognl.jsp</result>
	  	</action>
	 */
	@Action(value="demo10",results= {
			@Result(name="success",type="dispatcher",location="/ognl.jsp"),
			@Result(name="login",type="redirect",location="/ognl.jsp")
	})
	@Override
	public String execute() throws Exception {
		System.out.println("execute执行");
		return null;
	}

}

Struts2的工作流程

当tomcat服务器启动,Struts2先加载好各种配置文件,当一个请求过来时,会被前端控制器所拦截,然后就进入到StrutsPrepareAndExecuteFilter中,在其中创建了ActionContext还有ValueStack和Action等对象,然后还创建了ActionMapper对象,通过ActionMapper判断请求资源是否为Action,如果不是就直接正常放行,如果是则会进入到核心程序进行拦截过滤,在核心程序内部会创建一个代理Action,ActionProxy内部会调用ActionInvocation的一个方法invoke,这个方法按顺序会调用拦截器,一个拦截器执行完毕又会调用invoke方法,如果还有拦截器就继续执行,如果没有就执行action,然后action执行完毕就返回一个字符串,这个字符串又会经过之前的所有拦截器到达struts.xml中,在其中与result的name匹配,最终跳转到一个逻辑页面。
Struts2工作流程

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值