一 简介

(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:

  1. package cn.zifangsky.filter;
  2.  
  3. import java.io.IOException;
  4.  
  5. import javax.servlet.FilterChain;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9.  
  10. import org.springframework.web.filter.OncePerRequestFilter;
  11.  
  12. public class TestFilter1 extends OncePerRequestFilter {
  13.  
  14. protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
  15. throws ServletException, IOException {
  16. //在DispatcherServlet之前执行
  17. system.out.println("############TestFilter1 doFilterInternal executed############");
  18. filterChain.doFilter(request, response);
  19. //在视图页面返回给客户端之前执行,但是执行顺序在Interceptor之后
  20. System.out.println("############TestFilter1 doFilter after############");
  21. // try {
  22. // Thread.sleep(10000);
  23. // } catch (InterruptedException e) {
  24. // e.printStackTrace();
  25. // }
  26. }
  27.  
  28. }

ii)过滤器2:

  1. package cn.zifangsky.filter;
  2.  
  3. import java.io.IOException;
  4.  
  5. import javax.servlet.FilterChain;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9.  
  10. import org.springframework.web.filter.OncePerRequestFilter;
  11.  
  12. public class TestFilter2 extends OncePerRequestFilter {
  13.  
  14. protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
  15. throws ServletException, IOException {
  16. System.out.println("############TestFilter2 doFilterInternal executed############");
  17. filterChain.doFilter(request, response);
  18. System.out.println("############TestFilter2 doFilter after############");
  19.  
  20. }
  21.  
  22. }

2)再定义两个拦截器:

i)拦截器1,基本拦截器:

  1. package cn.zifangsky.interceptor;
  2.  
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5.  
  6. import org.springframework.web.servlet.HandlerInterceptor;
  7. import org.springframework.web.servlet.ModelAndView;
  8.  
  9. public class BaseInterceptor implements HandlerInterceptor{
  10.  
  11. /**
  12. * 在DispatcherServlet之前执行
  13. * */
  14. public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
  15. System.out.println("************BaseInterceptor preHandle executed**********");
  16. return true;
  17. }
  18.  
  19. /**
  20. * 在controller执行之后的DispatcherServlet之后执行
  21. * */
  22. public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
  23. throws Exception {
  24. System.out.println("************BaseInterceptor postHandle executed**********");
  25. }
  26.  
  27. /**
  28. * 在页面渲染完成返回给客户端之前执行
  29. * */
  30. public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
  31. throws Exception {
  32. System.out.println("************BaseInterceptor afterCompletion executed**********");
  33. // Thread.sleep(10000);
  34. }
  35.  
  36. }

ii)指定controller请求的拦截器:

  1. package cn.zifangsky.interceptor;
  2.  
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5.  
  6. import org.springframework.web.servlet.HandlerInterceptor;
  7. import org.springframework.web.servlet.ModelAndView;
  8.  
  9. public class TestInterceptor implements HandlerInterceptor {
  10.  
  11. public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
  12. System.out.println("************TestInterceptor preHandle executed**********");
  13. return true;
  14. }
  15.  
  16. public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
  17. throws Exception {
  18. System.out.println("************TestInterceptor postHandle executed**********");
  19. }
  20.  
  21. public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
  22. throws Exception {
  23. System.out.println("************TestInterceptor afterCompletion executed**********");
  24. }
  25. }

iii)在SpringMVC的配置文件中注册这两个拦截器:

  1. <!-- 拦截器 -->
  2. <mvc:interceptors>
  3. <!-- 对所有请求都拦截,公共拦截器可以有多个 -->
  4. <bean name="baseInterceptor" class="cn.zifangsky.interceptor.BaseInterceptor" />
  5. <!-- <bean name="testInterceptor" class="cn.zifangsky.interceptor.TestInterceptor" /> -->
  6. <mvc:interceptor>
  7. <!-- 对/test.html进行拦截 -->
  8. <mvc:mapping path="/test.html"/>
  9. <!-- 特定请求的拦截器只能有一个 -->
  10. <bean class="cn.zifangsky.interceptor.TestInterceptor" />
  11. </mvc:interceptor>
  12. </mvc:interceptors>

(3)定义一个测试使用的controller:

  1. package cn.zifangsky.controller;
  2.  
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.servlet.ModelAndView;
  6.  
  7. @Controller
  8. public class TestController {
  9.  
  10. @RequestMapping("/test.html")
  11. public ModelAndView handleRequest(){
  12. System.out.println("---------TestController executed--------");
  13. return new ModelAndView("test");
  14. }
  15. }

4)视图页面test.jsp:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <%
  4. String path = request.getContextPath();
  5. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  6. %>
  7. <html>
  8. <head>
  9. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  10. <base href="http://983836259.blog.51cto.com/7311475/">
  11. <title>FilterDemo</title>
  12. </head>
  13. <body>
  14. <%
  15. System.out.println("test.jsp is loading");
  16. %>
  17. <div align="center">
  18. This is test page
  19. </div>
  20. </body>
  21. </html>

SpringMVC的拦截器和过滤器的区别的更多相关文章

  1. Java Web 拦截器和过滤器的区别

    一.AOP:面向切面编程,Java Web中有两个常用的技术:拦截器.过滤器 二.拦截器 1.定义:在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作 2.原理:大部分时候,拦截器方法都 ...

  2. Struts2拦截器和过滤器的区别?

    ①过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容器. ②Struts2 拦截器只能对Action请求起作用,而过滤器则可以对几乎所 有请求起作用. ③拦截器可以访问 Action上下 ...

  3. 面试题:struts 拦截器和过滤器

    拦截器和过滤器的区别 过滤器是servlet规范中的一部分,任何java web工程都可以使用. 拦截器是struts2框架自己的,只有使用了struts2框架的工程才能用. 过滤器在url-patt ...

  4. Spring拦截器和过滤器

    什么是拦截器 拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在方法执行之前或之后加入某些操作,其实就是AOP的一种实现策略.它通过动态拦截Action调用的对象,允许开发者 ...

  5. springMVC拦截器和过滤器总结

    拦截器: 用来对访问的url进行拦截处理 用处: 权限验证,乱码设置等 spring-mvc.xml文件中的配置: <beans xmlns="http://www.springfra ...

  6. java 拦截器和过滤器区别(转载)

    1.拦截器是基于java的反射机制的,而过滤器是基于函数回调 2.过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3.拦截器只能对action请求起作用,而过滤器则可以对几乎所有的 ...

  7. SpringMVC学习笔记:拦截器和过滤器

    首先说明一下二者的区别: 1. 拦截器基于java的反射机制,而过滤器是基于函数回调 2. 拦截器不依赖于servlet容器,过滤器依赖servlet容器 3. 拦截器只能对action请求起作用,而 ...

  8. struts2拦截器和过滤器区别

    1.拦截器是基于java反射机制的,而过滤器是基于函数回调的.2.过滤器依赖于servlet容器,而拦截器不依赖于servlet容器.3.拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请 ...

  9. Spring Boot2(七):拦截器和过滤器

    一.前言 过滤器和拦截器两者都具有AOP的切面思想,关于aop切面,可以看上一篇文章.过滤器filter和拦截器interceptor都属于面向切面编程的具体实现. 二.过滤器 过滤器工作原理 从上图 ...

随机推荐

  1. 让Angular自定义组件支持form表单验证

    Angular提供了一套非常强大的表单验证库(vue和react都需要第三方库的支持),可以非常方便简单实现web应用程序中的表单验证功能.但是如何让我们自定义的组件也支持验证呢? 我遇到一个需求是封 ...

  2. rJava在ubuntu上的安装

    1.Oracle JDK 8(必须装oracle的,open的不行) http://www.cnblogs.com/loca/p/4679110.html Install Oracle JDK 8 o ...

  3. mysql - 按条件统计

    在表中分别统计mt =0 和 mt>0 的个数 方法一:select count(if(mt=0,1,null)) as a,count(if(mt>0,1,null)) as b fro ...

  4. Java基础——ArrayList方法全解(字典版)

    引言 在使用集合 ArrayList 的时候,经常使用add.remove等,其他的没用过,甚至没听说过的还有很多.现在在这个教程中,简单的了解一下,不要求全都记下.相当于在你脑袋里建一个索引,就是有 ...

  5. 使用JavaMailSender 发送邮件

    使用JavaMailSender 发送邮件 package com.juvenxu.mvnbook.account.email; import javax.mail.MessagingExceptio ...

  6. vue源码解析之observe

    一. vue文档中有"由于 JavaScript 的限制,Vue 不能检测以下数组的变动",是否真是由于JavaScript的限制,还是出于其他原因考虑 当你利用索引直接设置一个数 ...

  7. jquey 定位到有某个类

    $active = $('.g-pop-box .box-option a[class="on"]')

  8. ajax()返回Array

    后台查询的数据为数组$arr,需要将数组 echo json_encode($arr);前台ajax拿到数据 然后用 eval("(+data+)"); 来将json转为json对 ...

  9. 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

  10. 未知高度-纯css实现水平垂直居中

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...