网站首页 > 编程文章 正文
上周有个朋友在面试中被问题倒拦截器和过滤器,第一印象可能会感觉到这两个玩意不就是都可以做日志打印、权限功能...
好吧,咱们今天聊一聊过滤器和拦截器。
前言
1、拦截器(Interceptor)只对action请求起作用即对外访问路径,而过滤器(Filter)则可以对几乎所有的请求都能起作用 包括css、js等资源文件
2、拦截器(Interceptor)是在Servlet和Controller控制器之间执行,而过滤器(Filter)是在请求进入Tomcat容器之后但是在请求进入Servlet之前执行,在请求结束返回时也是一样,是在Servlet处理完之后返回给前端之间执行
web.xml加载顺序:context- param -> listener -> filter -> servlet
拦截器和过滤器的代码实现
拦截器
首先需要一个拦截器类 并且这个类要实现HandlerInterceptor接口 这个接口里面有三个方法:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
// 在拦截点(Controller方法处理之前)执行拦截 若返回的是false则中断执行 反之亦然
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
{
// 在处理过程中(Controller方法处理完之后 DispatcherServlet进行视图的渲染之前)执行拦截
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception
{
// 在DispatcherServlet进行视图的渲染后 返回前进行拦截
}
简单写一下方法:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
// 在Controller方法处理之前执行拦截 若返回的是false则中断执行 反之亦然
// 判断当前的User是否为空 若不为空则不拦截
if (request.getSession().getAttribute("USERINFO")!=null)
{
return true;
}
// 进行拦截 返回登录界面
response.sendRedirect(request.getContextPath()+"/user/doLogin.do");
return false;
}
然后需要去SpringMVC的配置文件中配置拦截器:
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截所有的mvc控制器(Controller) -->
<mvc:mapping path="/**"/>
<!-- 放行机制 指定对某个页面不进行拦截 -->
<!-- 拦截器只对action起作用 因此填入的不是页面路径 而是方法 -->
<mvc:exclude-mapping path="/user/doLogin.do"/>
<!-- 指定使用哪个拦截器 -->
<bean class="net.zjitc.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
如此当访问的请求不为/user/doLogin.do会被拦截然后重定向到/user/doLogin.do
但是访问其它的页面不会被拦截,想要让页面也被拦截?你需要过滤器
过滤器
同理需要一个过滤器类 然后实现javax.servlet.Filter接口
注意Filter的路径别导错了,因为有很多同名接口
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
// 过滤器初始化
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
{
}
@Override
public void destroy()
{
// 过滤器销毁
}
}
简单写一下方法:
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
{
// ServletRequest是一个接口 而HttpServletRequest是接口的实现
// 但有些方法是HttpServletRequest独有的 例如getSession()
// HttpServletRequest接口继承自ServletRequest接口 增加了和Http相关的方法
// 但是我们可以强制转换
HttpServletRequest request=(HttpServletRequest)servletRequest;
HttpServletResponse response=(HttpServletResponse)servletResponse;
// 若用户没有登录
if (request.getSession().getAttribute("USERINFO")==null && request.getRequestURI().indexOf("/user/doLogin.do")==-1)
{
response.sendRedirect(request.getContextPath()+"/user/doLogin.do");
}
// 若用户已经登录 则继续下一个请求(继续访问)
filterChain.doFilter(request,response);
}
然后需去web.xml中配置过滤器:
<!-- 配置自定义的Filter 实现登录控制 -->
<filter>
<filter-name>sessionFilter</filter-name>
<filter-class>net.zjitc.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<!-- 拦截所有的页面 /斜杠代表在webapp目录下 -->
<url-pattern>/pages/*</url-pattern>
<url-pattern>/css/*</url-pattern>
<url-pattern>/img/*</url-pattern>
<url-pattern>/failer.jsp</url-pattern>
</filter-mapping>
什么是Filter及其作用介绍
概念
Servlet规范中三个技术 Servlet Listener Filter(顺序为L F S) Filter是sun公司中servlet2.3后增加的一个新功能,在javaEE中定义了一个接口 javax.servlet.Filter来描述过滤器
作用
通过Filter可以拦截访问web资源的请求与响应操作,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
举例
在java web中,针对传入的request,或response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符。
Filter API介绍
Filter是javax.servlet包下的一个接口主要有以下三个方法
destory()
doFilter(ServletRequest request,ServletResponse response,FilterCjain chain)
init(FilterConfig filterConfig)
Filter链介绍
多个Filter对同一个资源进行了拦截,那么当我们在开始的Filter中执行chain.doFilter(request,response)时,是访问下一下Filter,直到最后一个Filter执行时,它后面没有了Filter,才会访问web资源。
多个Filter的访问顺序问题
执行顺序取决于在web.xml文件中配置的先后顺序。
Filter生命周期
- 当服务器启动,会创建Filter对象,并调用init方法,只调用一次.
- 当访问资源,路径与Filter的拦截路径匹配,会执行Filter中的doFilter方法,这个方法是真正拦截操作的方法.
- 当服务器关闭时,会调用Filter的destroy方法来进行销毁操作
- 过滤器是JavaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。
拦截器
拦截器是spring容器的,是spring支持的
java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。
在面向切面编程AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前进行拦截,然后在之前或之后加入某些操作。
比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
过滤器和拦截器的区别
- 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
- 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
- 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
- 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
- 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
- 拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。拦截器可以获取ioc中的service bean实现业务逻辑。
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
Spring MVC中每个控制器中可以定义多个请求处理方法,我们把这种请求处理方法简称为Action
总结
- 拦截器和过滤器其实都是AOP编程思想的实现,只不过过滤器是基于函数回调的,拦截器则是基于Java的反射机制(动态代理)实现的,都可以体现例如权限的检查日志的记录等功能
- 过滤器实现的是javax.servlet.Filter接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。
- 拦截器(Interceptor)它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中
- 过滤器Filter执行了两次,拦截器Interceptor只执行了一次
猜你喜欢
- 2025-05-09 Spring Boot3 RESTful 接口参数校验,这篇吃透就够了!
- 2025-05-09 《Spring6》第02节:基于XML方式搭建Spring6框架开发环境
- 2025-05-09 MapStruct架构设计(mapstruct @mapping)
- 2025-05-09 分布式微服务架构组件(分布式微服务架构设计)
- 2025-05-09 Java Swing组件下的JButton实例(java swing 组件)
- 2025-05-09 java基础都在这了,小主们拿去吧(java基础是指什么)
- 2025-05-09 AOP的实现落地(拦截过滤),一切都要从Servlet说起
- 2025-05-09 【Spring Boot】WebSocket 的 6 种集成方式
- 2025-05-09 Java 中五种最常见加密算法:原理、应用与代码实现
- 2025-05-09 用注解进行参数校验,spring validation介绍、使用、实现原理分析
你 发表评论:
欢迎- 05-09Spring Boot3 RESTful 接口参数校验,这篇吃透就够了!
- 05-09《Spring6》第02节:基于XML方式搭建Spring6框架开发环境
- 05-09MapStruct架构设计(mapstruct @mapping)
- 05-09分布式微服务架构组件(分布式微服务架构设计)
- 05-09Java Swing组件下的JButton实例(java swing 组件)
- 05-09java基础都在这了,小主们拿去吧(java基础是指什么)
- 05-09AOP的实现落地(拦截过滤),一切都要从Servlet说起
- 05-09【Spring Boot】WebSocket 的 6 种集成方式
- 最近发表
-
- Spring Boot3 RESTful 接口参数校验,这篇吃透就够了!
- 《Spring6》第02节:基于XML方式搭建Spring6框架开发环境
- MapStruct架构设计(mapstruct @mapping)
- 分布式微服务架构组件(分布式微服务架构设计)
- Java Swing组件下的JButton实例(java swing 组件)
- java基础都在这了,小主们拿去吧(java基础是指什么)
- AOP的实现落地(拦截过滤),一切都要从Servlet说起
- 【Spring Boot】WebSocket 的 6 种集成方式
- Java 中五种最常见加密算法:原理、应用与代码实现
- 用注解进行参数校验,spring validation介绍、使用、实现原理分析
- 标签列表
-
- spire.doc (59)
- system.data.oracleclient (61)
- 按键小精灵源码提取 (66)
- pyqt5designer教程 (65)
- 联想刷bios工具 (66)
- c#源码 (64)
- graphics.h头文件 (62)
- mysqldump下载 (66)
- sqljdbc4.jar下载 (56)
- libmp3lame (60)
- maven3.3.9 (63)
- 二调符号库 (57)
- 苹果ios字体下载 (56)
- git.exe下载 (68)
- diskgenius_winpe (72)
- pythoncrc16 (57)
- solidworks宏文件下载 (59)
- qt帮助文档中文版 (73)
- satacontroller (66)
- hgcad (64)
- bootimg.exe (69)
- android-gif-drawable (62)
- axure9元件库免费下载 (57)
- libmysqlclient.so.18 (58)
- springbootdemo (64)
本文暂时没有评论,来添加一个吧(●'◡'●)