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

Struts2拦截器

2018年06月05日 ⁄ 综合 ⁄ 共 4037字 ⁄ 字号 评论关闭

拦截器是struts2的一个重要特性。struts2框架的大多数核心功能都是通过拦截器来实现的,像避免表单重复提交、类型转换、对象组装、验证、文件上传等,都是在拦截器的帮助下实现的。之所以称为"拦截器",是因为它可以在Action执行之前和执行之后拦截调用。

Struts2将它的核心功能放到拦截器中实现,而不是分散到Action中实现,有利于系统的解耦,使得功能的实现类似于个人电脑的组装,变成了可插拔的,需要某个功能就“插入”一个拦截器,不需要某个功能就"拔出"一个拦截器。开发者可以任意组合拦截器来为Action提供附加的功能,而不需要修改Action的代码。

拦截器栈:

从结构上看,拦截器栈相当于多个拦截器的组合,从功能是看,拦截器栈也是拦截器。

多个拦截器的执行顺序:

注:从图中可以看出在执行Action之前会依次执行拦截器,调用Action中方法之后,会反向执行拦截器,然后跳转到对应的结果视图。

Struts2默认拦截器栈:

struts-default.xml中定义了一个defaultStack拦截器栈,并将其指定为默认拦截器。这就是为什么我们在定义包的时候要继承struts-default,因为我们不可能手动编写系统大量的拦截器,如果我们继承了struts-default,那么我们自然就可以使用系统所有内置的拦截器咯!

在strtus-default.xml中定义了大量拦截器,这些拦截器是以name-class对形式配置的:

这些内置的拦截器,一般情况下,是不需要手动去控制的,只要我们在struts.xml文件中定义包的时候继承struts-default即可。

自定义拦截器:

方式一:实现Interceptor接口

方式二:继承AbstractInterceptor类,此类实现了Interceptor接口

方式三:继承MethodFilterInterceptor,这个类可以实现方法的过滤拦截(非常实用,当我们想排除某些方法或特意之定义某些要拦截的方式时使用)

注:MethodFilterInterceptor拦截器中的includeMethods优先于execludeMethods,也就是说如果某个方法同时出现在了这两个参数中,那么会被当做要拦截的方法。

拦截器是无状态的,也就是说在拦截器类中不应该有实例变量。

下面列出一些开发当中常用的拦截器:

编码拦截器:

public class EncodingInterceptor extends AbstractInterceptor {

	private static final long serialVersionUID = 1L;

	public String intercept(ActionInvocation actionInvocation) throws Exception {
		
		ServletActionContext.getResponse().setCharacterEncoding("utf-8");
		ServletActionContext.getRequest().setCharacterEncoding("utf-8");
		return actionInvocation.invoke();
	}

}

session拦截器:

public class SessionInterceptor extends MethodFilterInterceptor {

	
	private static final long serialVersionUID = 1L;

	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		
		/*获取用户登录session*/
		SessionInfo sessionInfo = (SessionInfo) ServletActionContext.getRequest().getSession().getAttribute("sessionInfo");
		
		if (sessionInfo == null){
			
			/*设置提示信息*/
			ServletActionContext.getRequest().setAttribute("msg", "登录超时,请重新登录!");
			
			/*跳转到相关界面*/
			return "noSession";
		}
		
		/*如果session有值的话,就继续执行*/
		return invocation.invoke();
	}

}

权限拦截器:

public class AuthInterceptor extends MethodFilterInterceptor {

	
	private static final long serialVersionUID = 1L;

	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		
		/*获取action的上下文*/
		//ActionContext actionContext = invocation.getInvocationContext();
		/*获取用户session信息*/
		SessionInfo sessionIfno = (SessionInfo) ServletActionContext.getRequest().getSession().getAttribute("sessionInfo");
		
		/*获取用户当前的请求路径*/
		String authUrl = RequestUtils.getServletPath(ServletActionContext.getRequest());
		
		/*获取用户所有的权限url*/
		String allAuthUrls = sessionIfno.getAuthUrls();
		
			
		if (allAuthUrls.contains(authUrl)){
			
			return invocation.invoke();
		} else {
			ServletActionContext.getRequest().setAttribute("msg", "您没有访问此功能的权限!");
			
			return "noAuth";
		}
	}

}

struts.xml文件:

<package name="basePackage" extends="struts-default" namespace="/">
		<!-- 首先声明拦截器,再为每个拦截器都要配置自己的拦截栈,一定要显示声明系统的默认拦截器栈 -->
		<interceptors>

			<!-- 字符集拦截器 -->
			<interceptor name="encodingInterceptor" class="com.lixue.web.interceptor.EncodingInterceptor" />

			<interceptor-stack name="encodingStack">
				<interceptor-ref name="defaultStack"></interceptor-ref>
				<interceptor-ref name="encodingInterceptor"></interceptor-ref>
			</interceptor-stack>

			

			<!-- session拦截器 -->
			<interceptor name="sessionInterceptor" class="com.lixue.web.interceptor.SessionInterceptor" />
			<interceptor-stack name="sessionStack">
				<interceptor-ref name="encodingStack"></interceptor-ref>
				<interceptor-ref name="sessionInterceptor">
					<param name="excludeMethods">userLogin</param>
				</interceptor-ref>
			</interceptor-stack>

			<!-- 权限拦截器 -->
			<interceptor name="authInterceptor" class="com.lixue.web.interceptor.AuthInterceptor" />
			<interceptor-stack name="authStack">
				<interceptor-ref name="sessionStack"></interceptor-ref>
				<interceptor-ref name="authInterceptor">
					<param name="excludeMethods">treeGrid,userLogin,userLogout,dataGrid,doNotNeedSession_*,doNotNeedAuth_*</param>
				</interceptor-ref>
			</interceptor-stack>

		</interceptors>

		<!-- 系统的缺省配置是<interceptor-ref name="defaultStack"> 但是我们自定义了拦截器,所以我们引用的就不是缺省配置了,而是我们自定义的拦截栈 -->
		<!-- 这里name值是拦截器栈的名称 -->
		<default-interceptor-ref name="authStack"></default-interceptor-ref>

		<global-results>
			<result name="noAuth">/error/noAuth.jsp</result>
			<result name="noSession">/error/noSession.jsp</result>
			<result name="strutsException">/error/strutsException.jsp</result>
		</global-results>

	</package>

抱歉!评论已关闭.