拦截器——原理(AOP、责任链模式、配置)
1、Struts2拦截器概述:
(1)Struts2框架封装中封装了很多功能,这些功能其实都是封装在Struts2的拦截器里面,Struts2里面有很多拦截器,每次不是这些拦截器都执行,每次只执行默认的拦截器。

(2)Struts2默认拦截器的位置:

(3)拦截器在Action对象创建之后,action的方法执行之前执行。
2、Struts2底层原理:
(1)原理一(AOP思想):
AOP:面向切面(方面)编程,不通过修改源代码的方式来扩展功能。

在上面的登录流程图中,如果在登录成功后要添加用户的权限判断功能,不需要修改源代码。
(2)责任链模式(和过滤链模式思想相似):
过滤链模式:一个请求需要经过多个过滤器,而每个过滤器只有经过放行操作后才能进行下一步操作。
责任链模式:例如执行:添加、删除、修改操作,先执行添加操作,添加操作执行结束之后执行删除操作(类似于过滤链模式中的放行操作),执行删除操作之后执行修改操作。
3、AOP思想和责任链模式在Struts2中的应用:
(1)拦截器在Action对象创建之后,action的方法执行之前执行(在Action方法执行之前执行默认拦截器,执行过程中使用AOP思想,在Action中没有直接调用拦截器的方法,而是使用配置文件的方式进行操作)。
(2)如果拦截器执行过程中有多个拦截器则采用责任链模式进行,如果有三个拦截器,则先执行拦截器一,执行一之后做放行操作,然后执行拦截器二,做放行操作,最后执行拦截器三,放行后,执行Action方法。

4、过滤器和拦截器的区别:
(1)过滤器:过滤器理论上可以过滤任何内容,例如:图片、html、jsp、servlet的路径。
(2)拦截器:拦截器只能拦截Action。
5、servlet和action的区别:
(1)servlet:只在首次访问的时候创建,只创建一次(单实例对象)
(2)action:每次访问的时候创建,可以创建多次(多实例对象)
6、生命周期:
随项目的启动而创建,随项目的关闭而销毁。
7、拦截器的创建方法
(1)方法一:实现接口(需要实现三个方法,不推荐)
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class InterceptorDemo implements Interceptor {
@Override
public void destroy() { } @Override
public void init() { } @Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
return null;
}
}
(2)方法二:继承AbstractInterceptor类,因为该类已经实现了Interceptor接口,因此较为方便(帮我们实现了init和destory方法,就可以只实现intercept方法):
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class InterceptorDemo1 extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
return null;
}
}
(3)方法三:
public class InterceptorDemo2 extends MethodFilterInterceptor {
@Override
protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
actionInvocation.invoke();//放行
return null;
}
}
调用invoke()之前的代码叫做前处理,之后的代码叫做后处理。要是不想放行只需要返回一个字符串即可(不调用invoke()方法)。这样就不会执行后续的拦截器和Action,直接交给Result处理结果。
8、拦截器的配置
(1)先查看系统对拦截器的配置:
指明拦截器类:
<interceptors>
<interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
<interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
默认拦截器栈(20个拦截器):
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
指定默认拦截器栈:
<default-interceptor-ref name="defaultStack"/>
<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
(2)按照以上步骤配置自定义拦截器(在struts.xml文件中进行配置):
<struts>
<package name="action" namespace="/a" extends="struts-default">
<interceptors>
<interceptor name="MyInter" class="pers.zhb.interceptor.InterceptorDemo2"/>
<interceptor-stack name="MyStack">
<interceptor-ref name="MyInter"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref><!--引入默认的20个拦截器-->
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="MyStack"></default-interceptor-ref>
<action name="Demo1" class="pers.zhb.interceptor.InterceptorDemo1" method="execute">
<result name="success" type="dispatcher">/hello.jsp</result>
</action>
</package>
</struts>
配置拦截器共分为三个步骤:注册拦截器、注册拦截器栈、指定默认拦截器。在注册拦截器栈的时候需要将自己配置的拦截器放到系统的20个拦截器前面,这样可以保证拦截器的错误处理功能,以便在自定义拦截器出现错误的时候后面的拦截器作出处理。
创建一个Action,调用自定义的拦截器:
public class InterceptorDemo1 extends ActionSupport {
public String execute(){
System.out.println("我是调用拦截器的Action!");
return "success";
}
}
创建拦截器:
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
public class InterceptorDemo2 extends MethodFilterInterceptor {
@Override
protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
System.out.println("前处理");
actionInvocation.invoke();//放行
System.out.println("后处理");
return null;
}
}
其中invoke()方法可以调用拦截器。
测试结果:



9、对方法拦截的指定(即指定Action中哪些方法调用拦截器,哪些方法不调用拦截器)
(1)指定哪些方法不调用拦截器
struts.xml配置文件:
<package name="action" namespace="/a" extends="struts-default">
<interceptors>
<interceptor name="MyInter" class="pers.zhb.interceptor.InterceptorDemo2"/>
<interceptor-stack name="MyStack">
<interceptor-ref name="MyInter">
<param name="excludeMethods">add</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref><!--引入默认的20个拦截器-->
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="MyStack"></default-interceptor-ref>
<action name="Demo1_*" class="pers.zhb.interceptor.InterceptorDemo1" method="{1}">
<result name="success" type="dispatcher">/hello.jsp</result>
</action>
</package>
这里执行Action时用到了动态方法调用,画横线的一行指定了add方法不调用拦截器。
Action:
public class InterceptorDemo1 extends ActionSupport {
public String add(){
System.out.println("ADD");
return null;
}
public String delete(){
System.out.println("DELETE");
return null;
}
public String update(){
System.out.println("UPDATE");
return null;
}
public String selete(){
System.out.println("SELETE");
return null;
}
public String execute(){
System.out.println("我是调用拦截器的Action!");
return "success";
}
}
此Action中定义了四个方法,通过配置文件来指定哪些方法调用拦截器,哪些方法不调用拦截器。
调用拦截器的类:
public class InterceptorDemo2 extends MethodFilterInterceptor {
@Override
protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
System.out.println("前处理");
actionInvocation.invoke();//放行
System.out.println("后处理");
return null;
}
}
运行结果:

调用Action中的add方法时未调用拦截器。
(2)指定哪些方法拦截:
<param name="includeMethods">add</param>

只需修改配置文件中的如上的配置,上面的配置为:指定add方法调用拦截器,其他方法不调用拦截器。
拦截器——原理(AOP、责任链模式、配置)的更多相关文章
- Activiti工作流学习笔记(四)——工作流引擎中责任链模式的建立与应用原理
原创/朱季谦 本文需要一定责任链模式的基础,主要分成三部分讲解: 一.简单理解责任链模式概念 二.Activiti工作流里责任链模式的建立 三.Activiti工作流里责任链模式的应用 一.简单理解责 ...
- 【设计模式】Java设计模式 - 责任链模式
[设计模式]Java设计模式 - 责任链模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 目录 [设计模式]Java设计模式 - 责 ...
- es6 class中责任链模式与AOP结合
责任链模式大家应该都清楚,比如JS中的冒泡,Java中的拦截器.过滤器,都运用到了责任链模式. 可以看我之前的文章介绍责任链的:https://www.cnblogs.com/wuguanglin/p ...
- 设计模式之jdk动态代理模式、责任链模式-java实现
设计模式之JDK动态代理模式.责任链模式 需求场景 当我们的代码中的类随着业务量的增大而不断增大仿佛没有尽头时,我们可以考虑使用动态代理设计模式,代理类的代码量被固定下来,不会随着业务量的增大而增大. ...
- Struts2拦截器原理以及实例
一.Struts2拦截器定义 1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现. 2. ...
- Mybatis Interceptor 拦截器原理 源码分析
Mybatis采用责任链模式,通过动态代理组织多个拦截器(插件),通过这些拦截器可以改变Mybatis的默认行为(诸如SQL重写之类的),由于插件会深入到Mybatis的核心,因此在编写自己的插件前最 ...
- Java设计模式-责任链模式
提出问题: 最初接触责任链模式就是在struts2中,在当时学的时候看了一眼,大概知道了原理,最近在复习,模拟struts2,说是模拟只是大体模拟了struts2的工作流程,很多东西都是写死的,只是为 ...
- java责任链模式及项目实际运用
1.前言 上次我们认识了java责任链模式的设计,那么接下来将给大家展示责任链模式项目中的实际运用.如何快速搭建责任链模式的项目中运用. 2.简单技术准备 我们要在项目中使用借助这样的几个知识的组合运 ...
- 设计模式(一)Chain Of Responsibility责任链模式
设计模式篇章,源于网课的学习,以及个人的整理 在我们接收用户提交的字符时,常常会使用到过滤,在学习责任链模式前,我们是这样做的 1.定义一个类 public class MsgProcesser { ...
随机推荐
- C语言笔记--传递结构指针以及值传递,址传递
#include <stdio.h> #include <windows.h> #include <mmsystem.h> #include <string. ...
- HDU_5057_分块
http://acm.hdu.edu.cn/showproblem.php?pid=5057 分块,保存每个块中每位对应数字的和,复杂的是getmum,左右下标所在的块不能直接读取block数组,要重 ...
- 二、Mongodb常用命令
#进入admin数据库 use admin #进行权限认证 db.auth('userAdmin', '123456') #查询所有用户 db.system.users.find() #更新用户 db ...
- 1276:【例9.20】P2758 编辑距离
题目传送门[(https://www.luogu.com.cn/problem/P2758)] 题目描述 设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B.这里所说的字符操作 ...
- Linux系统基础认知
什么是操作系统? 操作系统作为接口的示意图: 没有安装操作系统的计算机,通常被称为裸机 如果想在 裸机 上运行自己所编写的程序,就必须用机器语言书写程序 如果计算机上安装了操作系统,就可以在操作系统上 ...
- android 基础学习笔记1
1.控件 XML种控件必须带有Layoutwidth 和height 1.textview 常用属性 text,textcolor,textsize Android 种颜色用十六进制数表示,共四种形式 ...
- python学习(1)python的基本概念
1.python是世界上最流行的程序语言之一,用途广泛. 2.python是解释型语言,与C++编译类语言相比,python扩展性强,简单易上手.但是缺点也很明显,执行速度慢. 3.python定义中 ...
- 某oa系统的审计
title: 某oa系统的审计 date: 2018-03-07 17:18:16 tags: --- 信呼OA 闲着没事,java学累了来整理下以前审的一个觉得很有意思的cms,这个作者写的比较灵活 ...
- Spring Cloud(七):服务网关zuul过滤器
上文介绍了Zuul的基本使用与路由功能,本文接着介绍Zuul的核心概念 -- Zuul过滤器(filter). Zuul的功能基本通过Zuul过滤器来实现(类比于Struts的拦截器,只是Struts ...
- JWT实现token-based会话管理(转)
JWT实现token-based会话管理 阅读目录 认识JWT demo要点说明 小结 上文<3种web会话管理的方式>介绍了3种会话管理的方式,其中token-based的方式有必要 ...