1.拦截器是Struts2的一大特色。拦截器可以让在当前执行的action所在的上下文之前或之后执行其他额外的操作。比如说,判断用户是否登录时,需要对每次请求都进行校验。但校验的逻辑通常是公共的,不应该直接写死在某个action类中,因此拦截器可以在action执行之前先进行校验,然后再进行正常的业务操作。
2.拦截器:用于在某个方法或字段被访问之前,进行拦截,然后在之前或之后加入某些操作。拦截是AOP(面向切面编程)的一种实现策略。
3.拦截器是Struts 2 MVC框架的重要组成部分,在Struts 2中,当我们需要使用某个拦截器时,只需要在配置文件中进行相关的配置即可;如果不需要某个拦截器,也只需要在配置文件中取消该拦截器的配置即可。不管是否应用某个拦截器,对于整个Struts 2框架不会产生任何的影响。这种设计方式,是一种可插拔式的设计,具有非常好的可扩展性。 Struts 2的拦截器体系是一种AOP(面向切面编程)的设计方式,它允许开发人员以一种简单的方式来进行AOP方式的开发。
4.Struts2拦截器结构的设计,是责任链模式的应用。 首先将整个执行划分成若干相同类型的元素,每个元素具备不同的逻辑责任,并将他们纳入到一个链式的数据结构中(堆栈结构也看作是一个递归的链式结构),每个元素又有责任负责链式结构中下一个元素的执行调用。
5.拦截器底层原理
6.拦截器接口。 所有的Struts2的拦截器都直接或间接实现接口com.opensymphony.xwork2.interceptor.Interceptor: void init(); 拦截器被初始化之后系统回调该方法。 void destroy(); 拦截器实例被销毁之前系统将回调该方法。 String intercept(ActionInvocation invocation) throws Exception; 该方法是用户需要实现的拦截动作。会返回一个字符串作为逻辑视图。 ActionInvocation是Action调度者, invocation.invoke()方法具备以下2层含义: 如果拦截器栈中还有其他的Interceptor,那么invocation.invoke()将调用栈中下一个Interceptor的执行。 如果拦截器栈中只有Action了,那么invocation.invoke()将调用Action执行。 在invocation.invoke()之前的代码,将会在Action之前被顺序执行,在invocation.invoke()之后的代码,将会在Action之后被逆序执行。 不使用invocation.invoke()来完成栈中下一个元素的调用,而是直接返回一个字符串作为执行结果,那么整个执行将被中止 继承类AbstractInterceptor是更简单的一种实现拦截器类的方式。
实现对访问页面的拦截,如果登录了这可以访问该页面,否则提示登录并跳转到登录页面。
(1)自定义拦截器类
package com.broccoli.interceptor; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; /* * 拦截器类 * @author zhanghongkuan */ public class LoginInterceptor extends MethodFilterInterceptor{ //这个方法里面写拦截器逻辑 protected String doIntercept(ActionInvocation invocation) throws Exception { //判断session里面是否有username的值 //获得session HttpServletRequest request = ServletActionContext.getRequest(); Object obj = request.getSession().getAttribute("username"); //判断 if(obj != null){ //登录状态 //做类似于放行的操作 return invocation.invoke(); } else{ //不是登录状态 //不执行action的方法,返回登录界面 return "loginFailure"; } } }(2)使用自定义拦截器: 在struts.xml配置中有两个步骤:
配置自定义拦截器:
<package name="my" namespace="/account" extends="struts-default"> <interceptors> <!-- 自定义拦截器 --> <interceptor name="logInterceptor" class="interceptor.LogInterceptor"> <param name="msg">QIUJY</param> </interceptor> <!-- 自定义拦截器栈 --> <interceptor-stack name="myStack"> <!-- 执行顺序与配置顺序有关 --> <interceptor-ref name="defaultStack" /> <interceptor-ref name="logInterceptor" /> </interceptor-stack> </interceptors> <action name="login" class="action.LoginAction"> <result name="success">/success.jsp</result> <interceptor-ref name="myStack" /> </action> </package>实例:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="demo1" namespace="/" extends="struts-default"> <!-- 声明自定义拦截器 --> <interceptors> <interceptor name="loginIntercept" class="com.broccoli.interceptor.LoginInterceptor"></interceptor> </interceptors> <action name="customer_*" class="com.broccoli.action.Customer" method="{1}"> <!-- 使用自定义拦截器 --> <interceptor-ref name="loginIntercept"> <!-- 配置action里面某些方法不进行拦截 name属性固定值:excludeMethods 值:方法名(不带括号,多个方法名称中间加逗号) --> <param name="excludeMethods">login</param> </interceptor-ref> <!-- 在action中手动配置默认拦截器 --> <interceptor-ref name="defaultStack"></interceptor-ref> <result name="loginSuccess">success.jsp</result> <result name="loginFailure">failure.jsp</result> </action> </package> </struts>(3)登录页面
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>用户登录</title> </head> <body> <form action="${pageContext.request.contextPath }/customer_login.action" method="post"> 用户名:<input name="username" type="text" ><br> 密 码 :<input name="password" type="password" ><br> <input type="submit" value="登录"> </form> </body> </html>此拦截器设置完成后会对action中的除login方法之外的其他方法进行拦截,同时也手工配置了默认拦截器,因为Struts2里面有很多默认拦截器,但是如果配置了自定义拦截器,默认的拦截器就不会执行。可以通过手工配置再次让默认拦截器自动执行。
