JavaWeb中Filter&Listener的神奇作用

您所在的位置:网站首页 javaweb中servlet的作用 JavaWeb中Filter&Listener的神奇作用

JavaWeb中Filter&Listener的神奇作用

#JavaWeb中Filter&Listener的神奇作用| 来源: 网络整理| 查看: 265

在这里插入图片描述

文章目录 1,Filter1.1 Filter概述1.2 Filter快速入门1.2.1 开发步骤 1.3 Filter执行流程1.4 Filter拦截路径配置1.5 过滤器链1.5.1 概述1.5.2 代码演示1.5.3 问题 2,Listener2.1 概述2.2 分类2.3 代码演示最后说一句

1,Filter 1.1 Filter概述

Filter 表示过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。

过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。

如下图所示,浏览器可以访问服务器上的所有的资源(servlet、jsp、html等)

在这里插入图片描述

而在访问到这些资源之前可以使过滤器拦截来下,也就是说在访问资源之前会先经过 Filter,如下图

在这里插入图片描述

拦截器拦截到后可以做什么功能呢? 在这里插入图片描述

过滤器一般完成一些通用的操作。比如每个资源都要写一些代码完成某个功能,我们总不能在每个资源中写这样的代码吧,而此时我们可以将这些代码写在过滤器中,因为请求每一个资源都要经过过滤器。

过滤器还可以做 统一编码处理、 敏感字符处理 等等…

1.2 Filter快速入门 1.2.1 开发步骤

进行 Filter 开发分成以下三步实现

定义类,实现 Filter接口,并重写其所有方法

在这里插入图片描述

配置Filter拦截资源的路径:在类上定义 @WebFilter 注解。而注解的 value 属性值 /* 表示拦截所有的资源

在这里插入图片描述

在doFilter方法中输出一句话,并放行

在这里插入图片描述

上述代码中的 chain.doFilter(request,response); 就是放行,也就是让其访问本该访问的资源。

1.3 Filter执行流程

在这里插入图片描述

如上图是使用过滤器的流程,我们通过以下问题来研究过滤器的执行流程:

放行后访问对应资源,资源访问完成后,还会回到Filter中吗?

从上图就可以看出肯定 会 回到Filter中

如果回到Filter中,是重头执行还是执行放行后的逻辑呢?

如果是重头执行的话,就意味着 放行前逻辑 会被执行两次,肯定不会这样设计了;所以访问完资源后,会回到 放行后逻辑,执行该部分代码。

通过上述的说明,我们就可以总结Filter的执行流程如下:

在这里插入图片描述

以后我们可以将对请求进行处理的代码放在放行之前进行处理,而如果请求完资源后还要对响应的数据进行处理时可以在放行后进行逻辑处理。 在这里插入图片描述

1.4 Filter拦截路径配置

拦截路径表示 Filter 会对请求的哪些资源进行拦截,使用 @WebFilter 注解进行配置。如:@WebFilter("拦截路径")

拦截路径有如下四种配置方式:

拦截具体的资源:/index.jsp:只有访问index.jsp时才会被拦截目录拦截:/user/*:访问/user下的所有资源,都会被拦截后缀名拦截:*.jsp:访问后缀名为jsp的资源,都会被拦截拦截所有:/*:访问所有资源,都会被拦截

通过上面拦截路径的学习,大家会发现拦截路径的配置方式和 Servlet 的请求资源路径配置方式一样,但是表示的含义不同。

1.5 过滤器链 1.5.1 概述

过滤器链是指在一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤器链。

如下图就是一个过滤器链,我们学习过滤器链主要是学习过滤器链执行的流程

在这里插入图片描述

上图中的过滤器链执行是按照以下流程执行: 在这里插入图片描述

执行 Filter1 的放行前逻辑代码执行 Filter1 的放行代码执行 Filter2 的放行前逻辑代码执行 Filter2 的放行代码访问到资源执行 Filter2 的放行后逻辑代码执行 Filter1 的放行后逻辑代码

以上流程串起来就像一条链子,故称之为过滤器链。

1.5.2 代码演示

编写第一个过滤器 FilterDemo ,配置成拦截所有资源

@WebFilter("/*") public class FilterDemo implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //1. 放行前,对 request数据进行处理 System.out.println("1.FilterDemo..."); //放行 chain.doFilter(request,response); //2. 放行后,对Response 数据进行处理 System.out.println("3.FilterDemo..."); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }

编写第二个过滤器 FilterDemo2 ,配置拦截所有资源

@WebFilter("/*") public class FilterDemo2 implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //1. 放行前,对 request数据进行处理 System.out.println("2.FilterDemo..."); //放行 chain.doFilter(request,response); //2. 放行后,对Response 数据进行处理 System.out.println("4.FilterDemo..."); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }

修改 hello.jsp 页面中脚本的输出语句

Title hello JSP~

启动服务器,在浏览器输入 http://localhost/filter-demo/hello.jsp 进行测试,在控制台打印内容如下

在这里插入图片描述

从结果可以看到确实是按照我们之前说的执行流程进行执行的。

1.5.3 问题

上面代码中为什么是先执行 FilterDemo ,后执行 FilterDemo2 呢?

我们现在使用的是注解配置Filter,而这种配置方式的优先级是按照过滤器类名(字符串)的自然排序。

比如有如下两个名称的过滤器 : BFilterDemo 和 AFilterDemo 。那一定是 AFilterDemo 过滤器先执行。

2,Listener 2.1 概述

Listener 表示监听器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。

监听器可以监听就是在 application,session,request 三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。

request 和 session 我们学习过。而 application 是 ServletContext 类型的对象。

ServletContext 代表整个web应用,在服务器启动的时候,tomcat会自动创建该对象。在服务器关闭时会自动销毁该对象。

2.2 分类

JavaWeb 提供了8个监听器:

在这里插入图片描述

这里面只有 ServletContextListener 这个监听器后期我们会接触到,ServletContextListener 是用来监听 ServletContext 对象的创建和销毁。

ServletContextListener 接口中有以下两个方法

void contextInitialized(ServletContextEvent sce):ServletContext 对象被创建了会自动执行的方法void contextDestroyed(ServletContextEvent sce):ServletContext 对象被销毁时会自动执行的方法 2.3 代码演示

我们只演示一下 ServletContextListener 监听器

定义一个类,实现ServletContextListener 接口重写所有的抽象方法使用 @WebListener 进行配置

代码如下:

@WebListener public class ContextLoaderListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { //加载资源 System.out.println("ContextLoaderListener..."); } @Override public void contextDestroyed(ServletContextEvent sce) { //释放资源 } }

启动服务器,就可以在启动的日志信息中看到 contextInitialized() 方法输出的内容,同时也说明了 ServletContext 对象在服务器启动的时候被创建了。

最后说一句

感谢大家的阅读,文章通过网络资源与自己的学习过程整理出来,希望能帮助到大家。

才疏学浅,难免会有纰漏,如果你发现了错误的地方,可以提出来,我会对其加以修改。

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3