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里面有很多默认***,但是如果配置了自定义***,默认的***就不会执行。可以通过手工配置再次让默认***自动执行。