Struts2之拦截器

1. 拦截器与Action的关系

Struts2框架的绝大部分功能都是通过拦截器来完成的,当StrutsPrepareAndExcuteFilter拦截到用户请求之后,大量拦截器将会对用户请求进行处理,然后才会调用用户开发的Action实例的方法处理请求。拦截器与Action之间的关系如下图。


2. 配置拦截器

1)        简单配置。

<!—通过指定拦截器名和拦截实现类来定义拦截器-->

<interceptor name=”拦截器名” class=”拦截器实现类”/>

 

2)        带参数的配置。

<!—通过指定拦截器名和拦截实现类来定义拦截器-->

<interceptor name=”拦截器名” class=”拦截器实现类”>

<!—下面元素可以出现0次,也可出现多次。其中name指定属性指定需要设置的参数,中间指定的就是该参数的值-->

<param name=”参数名”>参数值</param>

</interceptor>

 

3)        配置拦截器栈。

  <interceptor-stack name=”拦截器栈”>

<interceptor-ref name=”拦截器一”/>

<interceptor-ref name=”拦截器二”/>

 …

  </interceptor>

 

4)        配置默认拦截器。

  <package name=”包名”>

     <!—所有拦截和拦截器栈都配置在该元素下-->

<interceptors>

    <!—定义拦截器-->

    <interceptor…/>

    <!—定义拦截栈-->

     <interceptor-stack…/>

</interceptors>

<!—配置该包下的默认拦截器,既可以是拦截器,也可以是拦截栈-->

  <default-interceptor-ref name=”拦截器名或拦截器栈名”/>

   <action …/>

  </package>

3. 自定义拦截器

1)        实现拦截器类:SimpleInterceptor.java。

 public class SimpleInterceptor
	extends AbstractInterceptor
{
	// 简单拦截器的名字
	private String name;
	// 为该简单拦截器设置名字的setter方法
	public void setName(String name)
	{
		this.name = name;
	}
	public String intercept(ActionInvocation invocation)
		throws Exception
	{
		// 取得被拦截的Action实例
		LoginAction action = (LoginAction)invocation.getAction();
		// 打印执行开始的时间
		System.out.println(name + " 拦截器的动作---------" +
			"开始执行登录Action的时间为:" + new Date());
		// 取得开始执行Action的时间
		long start = System.currentTimeMillis();
		// 执行该拦截器的后一个拦截器
		// 如果该拦截器后没有其他拦截器,则直接执行Action的被拦截方法
		String result = invocation.invoke();
		// 打印执行结束的时间
		System.out.println(name + " 拦截器的动作---------" +
			"执行完登录Action的时间为:" + new Date());
		long end = System.currentTimeMillis();
		System.out.println(name + " 拦截器的动作---------" +
			"执行完该Action的时间为" + (end - start) + "毫秒");
		return result;
	}
}

2)        使用拦截器。在struts.xml文件中配置。

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<!-- 通过常量配置该应用所使用的字符集-->
	<constant name="struts.i18n.encoding" value="GBK"/>
	<!-- 配置本系统所使用的包 -->
	<package name="lee" extends="struts-default">
		<!-- 应用所需使用的拦截器都在该元素下配置 -->
		<interceptors>
			<!-- 配置mySimple拦截器 -->
			<interceptor name="mySimple"
			class="com.owen..app.interceptor.SimpleInterceptor">
				<!-- 为拦截器指定参数值 -->
				<param name="name">简单拦截器</param>
			</interceptor>
		</interceptors>

		<action name="login" class="com.owen.app.action.LoginAction">
			<result name="error">/WEB-INF/content/error.jsp</result>
			<result>/WEB-INF/content/welcome.jsp</result> 
			<!-- 配置系统的默认拦截器 -->
			<interceptor-ref name="defaultStack"/>
			<!-- 应用自定义的mySimple拦截器 -->
			<interceptor-ref name="mySimple">
				<param name="name">改名后的拦截器</param>
			</interceptor-ref>
		</action>
		<action name="*">
			<result>/WEB-INF/content/{1}.jsp</result>
		</action>
	</package>
</struts>

4. 拦截规定方法

在上面的例子,可以当你应用拦截器后,就会拦截所有相关的方法,这样并不是我们所需要的,我们希望是,可以让我们自己规定要拦截哪些方法,哪些方法不要拦截。那么这样怎么实现呢?在自定义拦截类,我们需要继承MethodFilterInterceptor的接口。下面能过个例子来理解。

1)        实现拦截器类:MyFilterInterceptor.java

public class MyFilterInterceptor
	extends MethodFilterInterceptor
{
	// 简单拦截器的名字
	private String name;
	// 为该简单拦截器设置名字的setter方法
	public void setName(String name)
	{
		this.name = name;
	}
	// 重写doIntercept()方法,实现对Action的拦截逻辑
	public String doIntercept(ActionInvocation invocation)
		throws Exception
	{
		// 取得被拦截的Action实例
		LoginAction action = (LoginAction)invocation.getAction();
		// 打印执行开始的时间
		System.out.println(name + " 拦截器的动作---------"
			+ "开始执行登录Action的时间为:" + new Date());
		// 取得开始执行Action的时间
		long start = System.currentTimeMillis();
		// 执行该拦截器的后一个拦截器,或者直接指定Action的被拦截方法
		String result = invocation.invoke();
		// 打印执行结束的时间
		System.out.println(name + " 拦截器的动作---------"
			+ "执行完登录Action的时间为:" + new Date());
		long end = System.currentTimeMillis();
		// 打印执行该Action所花费的时间
		System.out.println(name + " 拦截器的动作---------"
			+ "执行完该Action的时间为" + (end - start) + "毫秒");
		return result;
	}
}
2)使用拦截器。在struts.xml文件中配置。
  <?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<!-- 通过常量配置该应用所使用的字符集-->
	<constant name="struts.i18n.encoding" value="GBK"/>
<!-- 配置本系统所使用的包 -->
<package name="lee" extends="struts-default">
	<!-- 应用所需使用的拦截器都在该元素下配置 -->
	<interceptors>
		<!-- 配置mySimple拦截器 -->
		<interceptor name="mySimple"
		class="com.owen.app.interceptor.MyFilterInterceptor">
			<!-- 为拦截器指定参数值 -->
			<param name="name">拦截方法的拦截器</param>
		</interceptor>
	</interceptors>

	<action name="login" class="com.owen.app.action.LoginAction">
		<result name="error">/WEB-INF/content/error.jsp</result>
		<result>/WEB-INF/content/welcome.jsp</result> 
		<!-- 配置系统的默认拦截器 -->
		<interceptor-ref name="defaultStack"/>
		<!-- 应用自定义的mySimple拦截器 -->
		<interceptor-ref name="mySimple">
			<!-- 重新指定name属性的属性值 -->
			<param name="name">改名后的拦截方法过滤拦截器</param>
			<!-- 指定execute方法不需要被拦截 -->
			<param name="excludeMethods">execute</param>
		</interceptor-ref>
	</action>
	<action name="*">
		<result>/WEB-INF/content/{1}.jsp</result>
	</action>
</package>
</struts>

5. 实际应用

     下面笔者将实现这个的一个功能,当用户没有权限登录系统时,那么他的登录就会拦截下来,并且提示他没有权限登录系统。具体实现如下。

1)        实现拦截类:AuthorityInterceptor.java

 public class AuthorityInterceptor
	extends AbstractInterceptor
{
	// 拦截Action处理的拦截方法
	public String intercept(ActionInvocation invocation)
		throws Exception
	{
		// 取得请求相关的ActionContext实例
		ActionContext ctx = invocation.getInvocationContext();
		Map session = ctx.getSession();
		// 取出Session里的user属性
		String user = (String)session.get("user");
		//如果没有登录,或者登录所用的用户名不是owen,都返回重新登录
		if (user != null && user.equals("owen") )
		{
			return invocation.invoke();
		}
		// 如果没有登录,将服务器提示放入ActionContext中
		ctx.put("tip" ,"您还没有登录,请输入owen登录系统");
		// 返回login的逻辑视图
		return Action.LOGIN;
	}
}

2)        配置struts.xml的文件。

 <?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<constant name="struts.i18n.encoding" value="GBK"/>

	<package name="lee" extends="struts-default">
		<!-- 用户拦截器定义在该元素下 -->
		<interceptors>
			<!-- 定义了一个名为authority的拦截器 -->
			<interceptor name="authority" 
				class=" com.owen.app.interceptor.AuthorityInterceptor"/>
		</interceptors>

		<!-- 定义全局Result -->
		<global-results>
			<!-- 当返回login视图名时,转入loginForm.jsp页面 -->
			<result name="login">/WEB-INF/content/loginForm.jsp</result>
		</global-results>

		<action name="login" class="com.owen.app.action.LoginAction">
			<result name="error">/WEB-INF/content//error.jsp</result>
			<result>/WEB-INF/content/welcome.jsp</result>
		</action>
		<!-- 定义一个名为viewBook的Action,其实现类为ActionSupport -->
		<action name="viewBook">
			<!-- 返回success视图名时,转入viewBook.jsp页面 -->
			<result>/WEB-INF/content/viewBook.jsp</result>
			<interceptor-ref name="defaultStack"/>
			<!-- 应用自定义拦截器 -->
			<interceptor-ref name="authority"/>
		</action>
		<action name="*">
			<result>/WEB-INF/content/{1}.jsp</result>
		</action>
	</package>
</struts>

3)        JSP页面

  <body>
<h3>用户登录</h3>
${tip}
<s:form action="login">
	<s:textfield name="username" label="用户名"/>
	<s:password name="password" label="密码"/>
	<s:submit value="登录"/>
</s:form>
</body>

4)        结果图。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值