Jack Frost

JavaWeb–Servlet过滤器Filter和SpringMVC的HandlerInterceptor(Session和Cookie登录认证)

拦截一些请求进行处理,比如通过它来进行权限验证,或者是来判断用户是否登陆,日志记录,编码,或者限制时间点访问等等,是非常有必要的。所以就有了此篇文章啦。

文章结构:(1)Servlet过滤器Filter;(2)SpringMVC的HandlerInterceptor;(3)对比认知。

一、Servlet过滤器Filter:

此部分是从赵四大佬那里学来的,并补充自己的认知

(1)概念:

能够对Servlet容器的请求和响应对象进行检查和修改。

Servlet过滤器本身并不产生请求和响应对象,它只能提供过滤作用。Servlet过期能够在Servlet被调用之前检查Request对象,修改Request Header和Request内容;在Servlet被调用之后检查Response对象,修改Response Header和Response内容。

Servlet过期负责过滤的Web组件可以是Servlet、JSP或者HTML文件。

总之就是:实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。

(2)特点:

A.Servlet过滤器可以检查和修改ServletRequest和ServletResponse对象

B.Servlet过滤器可以被指定和特定的URL关联,只有当客户请求访问该URL时,才会触发过滤器

C.Servlet过滤器可以被串联在一起,形成管道效应,协同修改请求和响应对象

(3)作用:

A.查询请求并作出相应的行动。

B.阻塞请求-响应对,使其不能进一步传递。

C.修改请求的头部和数据。用户可以提供自定义的请求。

D.修改响应的头部和数据。用户可以通过提供定制的响应版本实现。

E.与外部资源进行交互。

(3)适用场合:

A.认证过滤

B.登录和审核过滤

C.图像转换过滤

D.数据压缩过滤

E.加密过滤

F.令牌过滤

G.资源访问触发事件过滤

H.XSL/T过滤

I.Mime-type过滤

(4)认知Filter接口源码:

(5)认知Filter为何可以拦截请求:(本博主找不到具体的代码调用,只能找到相关的几个接口估测)

FilterChain

FilterConfig。FilterConfig接口检索过滤器名、初始化参数以及活动的Servlet上下文。

博主猜测是:web服务器的底层源码机制的模板方法模式,默认调用doFilter时,先去执行filterClain的doFilter。从而进行拦截

(6)Servlet过滤器对响应的过滤过程:

A.过滤器截获客户端的请求

B.重新封装ServletResponse,在封装后的ServletResponse中提供用户自定义的输出流

C.将请求向后续传递

D.Web组件产生响应

E.从封装后的ServletResponse中获取用户自定义的输出流

F.将响应内容通过用户自定义的输出流写入到缓冲流中

G.在缓冲流中修改响应的内容后清空缓冲流,输出响应内容

(7)实例:(取自上文介绍的赵四大佬那里)

1. 注册:在web.xml

既然注册了,那实现呢?

接下来就是测试啦:

再着就是发布啦。注意下,我们先注册日志过滤器,然后注册编码器

这里写图片描述

(8)我们来看下注意事项:

A.由于Filter、FilterConfig、FilterChain都是位于javax.servlet包下,并非HTTP包所特有的,所以其中所用到的请求、响应对象ServletRequest、ServletResponse在使用前都必须先转换成HttpServletRequest、HttpServletResponse再进行下一步操作。

B.在web.xml中配置Servlet和Servlet过滤器,应该先声明过滤器元素,再声明Servlet元素

C.如果要在Servlet中观察过滤器生成的日志,应该确保在server.xml的localhost对应的元素中配置如下元素:

<Logger className = “org.apache.catalina.logger.FileLogger”

directory = “logs”prefix = “localhost_log.”suffix=”.txt”

timestamp = “true”/>


二、SpringMVC的HandlerInterceptor(给出一个登录功能的拦截Demo)

(1)springMVC拦截器的实现一般有两种方式:

第一种方式是要定义的Interceptor类要实现了Spring的HandlerInterceptor 接口

第二种方式是继承实现了HandlerInterceptor接口的类,比如Spring已经提供的实现了HandlerInterceptor接口的抽象类HandlerInterceptorAdapter

(2)概念及作用:

概念:Spring MVC允许你通过处理拦截拦截web请求,进行前置处理和后置处理。处理拦截是在Spring的web应用程序上下文中配置的,因此它们可以利用各种容器特性,并引用容器中声明的任何Bean。处理拦截是针对特殊的处理程序映射进行注册的,因此它只拦截通过这些处理程序映射的请求。

主要作用是拦截用户的请求并进行相应的处理,其他的作用比如通过它来进行权限验证,或者是来判断用户是否登陆,日志记录,或者限制时间点访问。

(3)认识HandlerInterceptor接口:

preHandle:

SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean 类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。

postHandle:

只能是在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用。Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行。

afterCompletion:

该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。 我们的系统日志的拦截在这个方法中,可以记录日志的相关的参数,检测方法的执行。

第一个和第二个方法分别是在处理程序处理请求之前和之后被调用的。第二个方法还允许访问返回的ModelAndView对象,因此可以在它里面操作模型属性。最后一个方法是在所有请求处理完成之后被调用的(如视图呈现之后).

(4)先来个Helloworld:

在springmvc配置文件那里配置拦截器,拦截的请求。

可以看到我一会实现的一个功能啦,登录的认证。

请求的实现:

这里写图片描述

这里写图片描述

(5)实现后台管理页面的登录拦截(其实就是面向前端的拦截)

作用是:就是在后台管理者登录之前,都必须经过登录才可进入管理界面,其他侵入性的接口也不可访问。

(一)注册我们的拦截器先:

WEB后台–基于Token的WEB后台登录认证机制(并讲解其他认证机制以及cookie和session机制)

(四)怎么去使用这个机制以及拦截器呢??

(五)演示:

这里写图片描述

登录成功

这里写图片描述

如果我们不登录,直接访问登录成功的url。结果如下:默认返回登录页面(因为我们拦截重定向了)

这里写图片描述

三、对比认知:阅读上文所述的接口并参考此文

(1)filter基于filter接口中的doFilter回调函数,interceptor则基于Java本身的反射机制;

比如HandlerInterceptor是交给spring bean工厂去反射生成的。

(2)filter是依赖于servlet容器的,没有servlet容器就无法回调doFilter方法,而interceptor与servlet无关;

(3)filter的过滤范围比interceptor大,filter除了过滤请求外通过通配符可以保护页面、图片、文件等,而interceptor只能过滤请求,只对controller起作用,在controller之前开始,在controller完成后结束(如被拦截,不执行action);

(4)filter的过滤一般在加载的时候在init方法声明,而interceptor可以通过在xml声明是guest请求还是user请求来辨别是否过滤;

(5)interceptor可以访问controller上下文、值栈里的对象,而filter不能;

(6)在controller的生命周期中,拦截器可以被多次调用,而过滤器只能在容器初始化时被调用一次。


更多内容,可以访问JackFrost的博客

码字很辛苦,转载请注明来自JackFrost《JavaWeb–Servlet过滤器Filter和SpringMVC的HandlerInterceptor(Session和Cookie登录认证)》

Leave a Reply

Your email address will not be published. Required fields are marked *