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都属于面向切面编程的具体实现. 二.过滤器 过滤器工作原理 从上图 ...
随机推荐
- 让Angular自定义组件支持form表单验证
Angular提供了一套非常强大的表单验证库(vue和react都需要第三方库的支持),可以非常方便简单实现web应用程序中的表单验证功能.但是如何让我们自定义的组件也支持验证呢? 我遇到一个需求是封 ...
- rJava在ubuntu上的安装
1.Oracle JDK 8(必须装oracle的,open的不行) http://www.cnblogs.com/loca/p/4679110.html Install Oracle JDK 8 o ...
- mysql - 按条件统计
在表中分别统计mt =0 和 mt>0 的个数 方法一:select count(if(mt=0,1,null)) as a,count(if(mt>0,1,null)) as b fro ...
- Java基础——ArrayList方法全解(字典版)
引言 在使用集合 ArrayList 的时候,经常使用add.remove等,其他的没用过,甚至没听说过的还有很多.现在在这个教程中,简单的了解一下,不要求全都记下.相当于在你脑袋里建一个索引,就是有 ...
- 使用JavaMailSender 发送邮件
使用JavaMailSender 发送邮件 package com.juvenxu.mvnbook.account.email; import javax.mail.MessagingExceptio ...
- vue源码解析之observe
一. vue文档中有"由于 JavaScript 的限制,Vue 不能检测以下数组的变动",是否真是由于JavaScript的限制,还是出于其他原因考虑 当你利用索引直接设置一个数 ...
- jquey 定位到有某个类
$active = $('.g-pop-box .box-option a[class="on"]')
- ajax()返回Array
后台查询的数据为数组$arr,需要将数组 echo json_encode($arr);前台ajax拿到数据 然后用 eval("(+data+)"); 来将json转为json对 ...
- Django < 2.0.8 任意URL跳转漏洞(CVE-2018-14574)
影响版本 Django < 2.0.8 抓包 访问http://192.168.49.2:8000//www.example.com,即可返回是301跳转到//www.example.com
- 未知高度-纯css实现水平垂直居中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...