struts2拦截器

拦截器是struts2的核心,struts2中的所有功能都是由一系列拦截器来实现的。拦截器和过滤器十分相似,过滤器过滤的是所有的请求,拦截器只过滤Action。并且在struts2中,所有功能都是可插拔的。在sturts2中还可以自定义拦截器来实现一些strut2中没有提供的功能。在struts2中拦截器的实现是通过代理来实现的(AOP)。在struts2中拦截器是单例的,所有action共享相同拦截器,所以在拦截器中定义常量时要注意线程安全的问题。

struts2提供了一系列默认的拦截器(拦截器栈)来实现功能。

struts2默认拦截器
拦截器说明
alias对于HTTP请求包含的参数设置别名
autowiring将某些JavaBean实例自动绑定到其他Bean对应的属性中,有点类似Spring的自动绑定
chain在web项目开发中,以前使用struts开发时经常碰到两个action互相传递参数或属性的情况。该拦截器就可以实现让前一个Action的参数可以在现有Action中使用。
conversionError从ActionContext中将转化类型时候发生的错误添加到Action的值域错误中,在校验时经常被使用到来显示类型转化错误的信息。
cookie从struts2.0.7版本开始,可以把cookie注入Action中设置的名字或值中。
createSession自动创建一个HTTP的session
debugging用来对在视图间传递的数据进行调试
execAndWait不显式执行Action,在视图上显示给用户的是一个等待的页面,但是action其实是在“背后”执行。该拦截器在对进度条进行开发时候特别有用。
exception将异常和action返回的result相映射。
fileUpload支持文件上传功能的拦截器。
i18n支持国际化的拦截器。
logger拥有日志功能的拦截器。
modelDrivenaction执行该拦截器时,可以将getModel方法得到的result值放入值栈中。
scopedModelDriven执行该拦截器的时候,它可以从一个scope范围检索和存储model值,通过调用setModel方法去设置model值
params将HTTP请求中包含的参数值设置到Action中
prepare假如Action继承了Preparable接口,则会调用prepare方法
staticParams对于在struts.xml文件中Action中设置的参数设置到对应的Action中
scope在session或者application范围中设置Action的状态
servletConfig该拦截器提供包含HttpServletRequest和HttpServletResponse对象的map方法
timer输出Action的执行时间
token避免重复提交的校验拦截器
tokenSession和token拦截器类似,但它还能存储提交的数据到session里
validation运行在action-validation.xml文件中定义的校验规则
workflow在action中调用validate校验方法,如果action有错误则返回到input视图
store执行校验功能时候,该拦截器提供存储和检索Action的所有错误和正确信息的功能
checkbox视图如果有checkbox存在的情况,该拦截器自动将unchecked的checkbox当做一个参数(通常值为“false”)记录下来。这样可以用一个隐藏的表单值来记录所有未提交的checkbox,而且缺省unchecked的checkbox值时布尔类型的,如果视图中checkbox的值设置的不是布尔类型,它就会被覆盖成布尔类型的值。
profiling通过参数来激活或者不激活分析检测功能,前提是web项目是在开发模式下。(涉及到调试和性能检验时使用)
roles进行权限配置的拦截器,如果登录用户拥有相应权限才去执行某一特定的Action
struts2默认拦截器的使用

struts2的默认拦截器是定义在struts-default.xml文件中的。这些拦截器都是定义在struts-default包下的,所以我们在使用struts2时定义的package要直接或者间接继承struts-default

使用步骤(timer)
  • web.xml
<!-- struts2的前端控制器 -->
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>*.action</url-pattern>
</filter-mapping>
  • 处理类
public class HelloAction {
	public String execute() {
		System.out.println("hello action be execute");
		return Action.SUCCESS;
	}
}
  • 拦截器
使用拦截器时,需要在指定的action中引用拦截器
<interceptor-ref name=""></interceptor-ref>
<struts>
	<package name="default" namespace="/" extends="struts-default">
		<action name="hello" class="com.x.action.HelloAction">
			<result name="success">/success.jsp</result>
			<interceptor-ref name="timer"></interceptor-ref>
		</action>
	</package>
</struts>
  • 访问即可使用,会在控制台输出该action的执行时间。
使用步骤(token)
  • web.xml
<!-- struts2的前端控制器 -->
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>*.action</url-pattern>
</filter-mapping>
  • 在页面中添加token标签
<%@ taglib prefix="s" uri="/struts-tags" %>
<body>
	<form action="save.action" method="post">
	<s:token></s:token>
		username:<input type="text" name="user.name"><br>
		password:<input type="password" name="user.password"><br>
		<input type="submit">
	</form>
</body>
  • 处理类
public class UserAction {
	private User user;
	//添加该方法是因为访问页面应当通过action,否则不安全。其次是因为在web.xml中,
	//配置的拦截为/*,所以直接访问页面不会报错,但是如果改为*.action,直接访问页面,token拦截器就不会被加载,会报错!!!
	public String toSave() {
		System.out.println("toSave");
		return Action.SUCCESS;
	}
	
	
	public String save() {
		System.out.println(user);
		return Action.SUCCESS;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	
}
  • 定义token拦截器
注意
如果表单重复提交,token拦截器会返回invalid.token,需要定义返回集
<struts>
	<package name="default" namespace="/" extends="struts-default">
		<action name="save" class="com.x.action.UserAction" method="save">
			<result>/success.jsp</result>
			<interceptor-ref name="token"></interceptor-ref>
			<result name="invalid.token">/login.jsp</result>
		</action>
		
		<action name="toSave" class="com.x.action.UserAction" method="toSave">
			<result>/login.jsp</result>
		</action>
	</package>
</struts>
  • 原理
    在这里插入图片描述

当定义token拦截器后,会生成一个令牌,值同上面的value,并且将该值存入session中。同时会在页面生成一个hidden标签,值为该令牌。当进行表单提交时,会检查session中有无此token,如果有,则进行判断是否相同,相同则为重复提交。如果是第一次提交,该session中没有此token,会将该token存入session,并且将表单提交。



struts2自定义拦截器

在开发过程中,经常会有使用到struts2没有提供的一些功能,这时,需要自定义拦截器实现。当引用自定义拦截器后,struts2提供的默认拦截器将不起作用,需要重新引入:<interceptor-ref name="defaultStack"></interceptor-ref>,里面有默认的18个默认拦截器,在struts-default.xml文件中可以查看。

实现方式(两种)
一、实现Interceptor接口
  • web.xml
<!-- struts2的前端控制器 -->
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>*.action</url-pattern>
</filter-mapping>
  • 定义处理类
public class HelloAction {
	public String execute() {
		System.out.println("hello action be execute");
		return Action.SUCCESS;
	}
}
  • 声明拦截器
说明
当拦截器方法被调用执行后,需要使用invocation.invoke调用下一个拦截器,如果没有拦截器那么执行Action中的业务方法
public class MyInterceptor implements Interceptor{
	//拦截器销毁
	public void destroy() {
		
	}
	//拦截器创建
	public void init() {
		
	}
	//拦截器主体实现
	public String intercept(ActionInvocation invocation) throws Exception {
		System.out.println("自定义拦截器执行");
		//返回值为结果集
		return invocation.invoke();
	}
}
  • 在struts.xml文件中配置拦截器
<struts>
	<package name="default" namespace="/" extends="struts-default">
		<!-- 拦截器的配置,name唯一 -->
		<interceptors>
			<interceptor name="my" class="com.x.interceptor.MyInterceptor"></interceptor>
		</interceptors>
	
		<action name="hello" class="com.x.action.HelloAction">
			<result name="success">/success.jsp</result>
			<!-- 自定义拦截器 -->
			<interceptor-ref name="my"></interceptor-ref>
		</action>
	</package>
</struts>
  • 结果
    在这里插入图片描述
二、继承AbstractInterceptor类(登录拦截器)

判断是否是登录的action,如果是,继续执行,如果不是,判断session中是否有用户存在。如果不存在,跳转到登录页面,如果存在,继续执行。

  • web.xml
<!-- struts2的前端控制器 -->
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>*.action</url-pattern>
</filter-mapping>
  • 定义拦截器类
public class LoginInterceptor extends AbstractInterceptor{
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		String actionName = invocation.getProxy().getActionName();
		if("login".equals(actionName)) {
			return invocation.invoke();
		}
		Object currentUser = invocation.getInvocationContext().getSession().get("currentUser");
		if(currentUser!=null) {
			return invocation.invoke();
		}
		return Action.LOGIN;
	}
}
  • 登录处理类
public class LoginAction {
	private User user;
	
	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String login() {
		if("name".equals(user.getName()) && "pwd".equals(user.getPassword())) {
			ActionContext.getContext().getSession().put("currentUser", user);
			return Action.SUCCESS;
		}
		return Action.LOGIN;
	}
}
  • sturts.xml,在需要登录拦截器的地方引用即可
<struts>
	<package name="default" namespace="/" extends="struts-default">
		<!-- 拦截器的配置,name唯一 -->
		<interceptors>
			<interceptor name="myLogin" class="com.x.interceptor.LoginInterceptor"></interceptor>
		</interceptors>
		
		<!-- 配置全局结果集 -->
		<global-results>
			<result name="login">/login.jsp</result>
		</global-results>
		
		<action name="login" class="com.x.action.LoginAction" method="login">
			<result name="success">/success.jsp</result>
			<!-- 自定义拦截器 -->
			<interceptor-ref name="myLogin"></interceptor-ref>
			<interceptor-ref name="defaultStack"></interceptor-ref>
		</action>
		
		<action name="save" class="com.x.action.UserAction" method="save">
			<result>/success.jsp</result>
			<interceptor-ref name="myLogin"></interceptor-ref>
		</action>
		
		<action name="toSave" class="com.x.action.UserAction" method="toSave">
			<interceptor-ref name="myLogin"></interceptor-ref>
			<result>/save.jsp</result>
		</action>
	</package>
</struts>


struts拦截器栈和方法拦截器

拦截器栈

拦截器栈就是一组拦截器,放在一个配置中,方便使用。当使用的拦截器较多时使用。拦截器栈可以引用其他的拦截栈。

<!-- 拦截器的配置,name唯一 -->
<interceptors>
	<interceptor name="myInterceptor" class="com.x.interceptor.MyInterceptor"></interceptor>
	<interceptor name="myLogin" class="com.x.interceptor.LoginInterceptor"></interceptor>
			<!-- 拦截器栈 -->
	<interceptor-stack name="myStack">
		<interceptor-ref name="myInterceptor"></interceptor-ref>
		<interceptor-ref name="myLogin"></interceptor-ref>
		<interceptor-ref name="defaultStack"></interceptor-ref>
	</interceptor-stack>
</interceptors>
  • 引用
<interceptor-ref name="myStack"></interceptor-ref>
  • 默认拦截器栈设置
    设置好后其下面的action不需要再引用。
<!-- 设置默认拦截器栈 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
方法拦截器

拦截器拦截的是整个action,action中的所有业务方法都会被拦截,比较粗粒度。有时只需拦截action中的某个方法就能实现功能。

方法拦截器的实现,继承MethodFilterInterceptor
  • web.xml
<!-- struts2的前端控制器 -->
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>*.action</url-pattern>
</filter-mapping>
  • 拦截器类
public class MethodInteceptor extends MethodFilterInterceptor {
	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		System.out.println("方法拦截器执行");
		return invocation.invoke();
	}
}
  • sturts.xml中配置
说明
其中的param参数为 MethodFilterInterceptor中的set方法名
<interceptors>
	<!-- 拦截器栈 -->
	<interceptor-stack name="myStack">
		<interceptor-ref name="methodInterceptor">
			<!-- 配置哪些方法被拦截 -->
			<param name="includeMethods">方法名,方法名,。。。</param>
			<!-- 配置哪些方法不被拦截 -->
			<param name="excludeMethods">方法名,方法名,。。。</param>
		</interceptor-ref>
		<interceptor-ref name="defaultStack"></interceptor-ref>
	</interceptor-stack>
</interceptors>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值