SpringMVC的拦截器和过滤器的区别
一 简介
(1)过滤器:
依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等
关于过滤器的一些用法可以参考我写过的这些文章:
继承HttpServletRequestWrapper以实现在Filter中修改HttpServletRequest的参数:https://www.zifangsky.cn/677.html
在SpringMVC中使用过滤器(Filter)过滤容易引发XSS的危险字符:https://www.zifangsky.cn/683.html
(2)拦截器:
依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理
关于过滤器的一些用法可以参考我写过的这些文章:
在SpringMVC中使用拦截器(interceptor)拦截CSRF攻击(修):https://www.zifangsky.cn/671.html
SpringMVC中使用Interceptor+cookie实现在一定天数之内自动登录:https://www.zifangsky.cn/700.html
二 多个过滤器与拦截器的代码执行顺序
如果在一个项目中仅仅只有一个拦截器或者过滤器,那么我相信相对来说理解起来是比较容易的。但是我们是否思考过:如果一个项目中有多个拦截器或者过滤器,那么它们的执行顺序应该是什么样的?或者再复杂点,一个项目中既有多个拦截器,又有多个过滤器,这时它们的执行顺序又是什么样的呢?
下面我将用简单的代码来测试说明:
(1)先定义两个过滤器:
i)过滤器1:
package cn.zifangsky.filter; import java.io.IOException; import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.filter.OncePerRequestFilter; public class TestFilter1 extends OncePerRequestFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
//在DispatcherServlet之前执行
system.out.println("############TestFilter1 doFilterInternal executed############");
filterChain.doFilter(request, response);
//在视图页面返回给客户端之前执行,但是执行顺序在Interceptor之后
System.out.println("############TestFilter1 doFilter after############");
// try {
// Thread.sleep(10000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
} }
ii)过滤器2:
package cn.zifangsky.filter; import java.io.IOException; import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.filter.OncePerRequestFilter; public class TestFilter2 extends OncePerRequestFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
System.out.println("############TestFilter2 doFilterInternal executed############");
filterChain.doFilter(request, response);
System.out.println("############TestFilter2 doFilter after############"); } }
2)再定义两个拦截器:
i)拦截器1,基本拦截器:
package cn.zifangsky.interceptor; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; public class BaseInterceptor implements HandlerInterceptor{ /**
* 在DispatcherServlet之前执行
* */
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("************BaseInterceptor preHandle executed**********");
return true;
} /**
* 在controller执行之后的DispatcherServlet之后执行
* */
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("************BaseInterceptor postHandle executed**********");
} /**
* 在页面渲染完成返回给客户端之前执行
* */
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("************BaseInterceptor afterCompletion executed**********");
// Thread.sleep(10000);
} }
ii)指定controller请求的拦截器:
package cn.zifangsky.interceptor; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; public class TestInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("************TestInterceptor preHandle executed**********");
return true;
} public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("************TestInterceptor postHandle executed**********");
} public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("************TestInterceptor afterCompletion executed**********");
}
}
iii)在SpringMVC的配置文件中注册这两个拦截器:
<!-- 拦截器 -->
<mvc:interceptors>
<!-- 对所有请求都拦截,公共拦截器可以有多个 -->
<bean name="baseInterceptor" class="cn.zifangsky.interceptor.BaseInterceptor" />
<!-- <bean name="testInterceptor" class="cn.zifangsky.interceptor.TestInterceptor" /> -->
<mvc:interceptor>
<!-- 对/test.html进行拦截 -->
<mvc:mapping path="/test.html"/>
<!-- 特定请求的拦截器只能有一个 -->
<bean class="cn.zifangsky.interceptor.TestInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
(3)定义一个测试使用的controller:
package cn.zifangsky.controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView; @Controller
public class TestController { @RequestMapping("/test.html")
public ModelAndView handleRequest(){
System.out.println("---------TestController executed--------");
return new ModelAndView("test");
}
}
4)视图页面test.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<base href="http://983836259.blog.51cto.com/7311475/">
<title>FilterDemo</title>
</head>
<body>
<%
System.out.println("test.jsp is loading");
%>
<div align="center">
This is test page
</div>
</body>
</html>
SpringMVC的拦截器和过滤器的区别的更多相关文章
- Java Web 拦截器和过滤器的区别
一.AOP:面向切面编程,Java Web中有两个常用的技术:拦截器.过滤器 二.拦截器 1.定义:在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作 2.原理:大部分时候,拦截器方法都 ...
- Struts2拦截器和过滤器的区别?
①过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容器. ②Struts2 拦截器只能对Action请求起作用,而过滤器则可以对几乎所 有请求起作用. ③拦截器可以访问 Action上下 ...
- 面试题:struts 拦截器和过滤器
拦截器和过滤器的区别 过滤器是servlet规范中的一部分,任何java web工程都可以使用. 拦截器是struts2框架自己的,只有使用了struts2框架的工程才能用. 过滤器在url-patt ...
- Spring拦截器和过滤器
什么是拦截器 拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在方法执行之前或之后加入某些操作,其实就是AOP的一种实现策略.它通过动态拦截Action调用的对象,允许开发者 ...
- springMVC拦截器和过滤器总结
拦截器: 用来对访问的url进行拦截处理 用处: 权限验证,乱码设置等 spring-mvc.xml文件中的配置: <beans xmlns="http://www.springfra ...
- java 拦截器和过滤器区别(转载)
1.拦截器是基于java的反射机制的,而过滤器是基于函数回调 2.过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3.拦截器只能对action请求起作用,而过滤器则可以对几乎所有的 ...
- SpringMVC学习笔记:拦截器和过滤器
首先说明一下二者的区别: 1. 拦截器基于java的反射机制,而过滤器是基于函数回调 2. 拦截器不依赖于servlet容器,过滤器依赖servlet容器 3. 拦截器只能对action请求起作用,而 ...
- struts2拦截器和过滤器区别
1.拦截器是基于java反射机制的,而过滤器是基于函数回调的.2.过滤器依赖于servlet容器,而拦截器不依赖于servlet容器.3.拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请 ...
- Spring Boot2(七):拦截器和过滤器
一.前言 过滤器和拦截器两者都具有AOP的切面思想,关于aop切面,可以看上一篇文章.过滤器filter和拦截器interceptor都属于面向切面编程的具体实现. 二.过滤器 过滤器工作原理 从上图 ...
随机推荐
- python 元组推导式
>>> b=(page for page in range(10))>>> print(b)<generator object <genexpr> ...
- MapReduce处理数据1
学了一段时间的hadoop了,一直没有什么正经练手的机会,今天老师给了一个课堂测试来进行练手,正好试一下. 项目已上传至github:https://github.com/yandashan/MapR ...
- C语言中函数的返回值
规则 除局部变量的内存地址不能作为函数的返回值外,其他类型的局部变量都能作为函数的返回值. 我总结出下面这些规则: int.char等数据类型的局部变量可以作为函数返回值. 在函数中声明的指针可以作为 ...
- Spring事务管理中的配置文件(三)
在开发中,遇到了sql语句报错,但是并没有回滚的情况. 经过几天的排查,终于找到了事务没有回滚的原因. 原来的项目用的是informix的数据库,原来针对事务回滚的机制都是好用的.我本地用的是mysq ...
- 微信小程序创建第一个项目
一.打开微信开发者工具,扫码登录 二.点击右侧的加号,添加小程序 第三步:创建成功后,报错 VM82:1 cloud init error: Error: invalid scope 没有权限,请先开 ...
- Adaptive AUTOSAR 学习笔记 10 - 执行管理
本系列学习笔记基于 AUTOSAR Adaptive Platform 官方文档 R20-11 版本 AUTOSAR_EXP_PlatformDesign.pdf 缩写 EM:Execution Ma ...
- MVC从客户端中检测到有潜在危险的Request.Form值的解决方法
1.ASPX页面 在页面头部的page中加入ValidateRequest="false" 2.web.config中配置validateRequest="false&q ...
- 通过cmake在Android中调用c语言,且三方应用通过so库调用c语言
1. 新建JniUtils类实现native方法 2. 在build中执行clean project 再rebuild project 生成class文件. 注意:最新版本的AndroidStud ...
- 表格技术七十二变|手把手教你用Canvas电子表格做电子签名
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 日常生活工作学习中,大家对电子表格必定不陌生.从工作数据汇总分析到出门收据各种电子发票,这些都是由电子表格制 ...
- DASCTF七月赛两道Web题复现
Ezfileinclude(目录穿越) 拿到http://183.129.189.60:10012/image.php?t=1596121010&f=Z3F5LmpwZw== t是时间,可以利 ...