过滤器和监听器

时间:2023-02-13 10:48:44

1 过滤器入门

1.1 引入

场景1:在servlet中获取用户参数数据  request.getParameter("参数名") 遇到参数内容中文乱码问题,

post提交:

request.setCharacterEncoding("utf-8");

get提交:

手动解码: name = new String(name.getBytes("iso-8859-1"),"utf-8")

问题: 如何把这些重复的操作抽取出来呢?

这时就可以用到过滤器,把重复的操作代码写在过滤器中!!!

场景2:登录页面 -> 输入用户民或密码 -  后台检查是否成功 - 登录成功,看到用户首页 ( 用户名:xxxx   )把登录数据放在session域对象中(user)用户首页如果不登录是看不到的:

判断用户登录权限代码:

HttpSession session = request.getSession(false);

if(session==null){

跳转到登陆页面

}else{

String user = (String)session.getAttribute("user");

if(user==null){

跳转到登录页面

}

}

用户资源修改页面(需要用户登录才能访问)

HttpSession session = request.getSession(false);

if(session==null){

跳转到登陆页面

}else{

String user = (String)session.getAttribute("user");

if(user==null){

跳转到登录页面

}

}

问题:如何把这些登录权限代码抽取出???

这是用到了过滤器,把这些登录权限代码写在过滤器中.

 

1.2 什么是过滤器?

1)过滤器就是一个Filter接口,在javax.servlet.Filter;

2)过滤器是servlet的三大组件之一:

servlet的三大组件:

2.1  (servlet) Servlet接口: javax.servlet.Servlet; 作用:用于开发动态网页

2.2 (过滤器)Filter接口: javax.servlet.Filter; 作用:???

2.3 (监听器)Listener接口: javax.servlet.*

servlet组件的特点:

1)把组件配置到web.xml文件中

2)组件就可以交给tomcat服务器运行!!!!

3)作用:

过滤器的作用,就是一个实现了Filter接口的对象,这个对象可以在请求资源(可能是动态网页或者静态网页)时,或者在响应资源时,或者在请求和响应资源时,执行过滤任务

1.3 过滤器的生命周期

构造方法: 创建过滤器对象的时候调用。在加载当前项目的时候加载过滤器,只调用1次。单实例的多线程。

init方法: 在创建完过滤器对象之后调用。只调用1次。

doFilter方法 过滤任务方法。会调用n次。每次访问目标资源的时候,doFilter就会被调用。

destory方法:在销毁过滤器对象的时候调用。在web项目重新部署或tomcat服务器停止的时候销毁过滤器对象。

2 映射配置

    <!-- 配置一个过滤器 -->

<!-- 过滤器配置 -->

<filter>

<!-- 内部名称 -->

<filter-name>FirstFilter</filter-name>

<filter-class>com.td.a_filter.FirstFilter</filter-class>

</filter>

<!-- 过滤器映射配置 -->

<filter-mapping>

<!-- 也是内部名称,但是和上面的名称保持一致!!! -->

<filter-name>FirstFilter</filter-name>

<!--过滤器的url-pattern代表的是过滤的路径,而不是访问过滤器的路径  -->

<url-pattern>/target</url-pattern>

</filter-mapping>

 

注意: servleturl-pattern指的是访问servlet的路径,而过滤器的url-pattern指的是需要过滤的路径。

而这个过滤的路径,可以是任意资源路径(可以是静态网页路径,页可以是动态网页路径)。

过滤器url-pattern                 访问目标资源

精确过滤   /target                      http://localhsot:8080/test/target

/index.html http://localhsot:8080/test/index.html

模糊过滤  /*                      http://localhsot:8080/test/任意路径

 /td/*                   http://localhsot:8080/test/td/任意路径

*.后缀名    http://localhsot:8080/test/任意路径.后缀名

*.do            http://localhsot:8080/test/任意路径.do

3 FilteConfig对象

3.1 简介

servletconfig对象类似,这个FilterConfig对象加载初始化参数内容

4 FilterChain对象

4.1 简介

FilterChain对象叫做过滤器链对象。

什么是过滤器链?   当一个资源被多个过滤器所过滤,那么就形成了一个过滤器链。

过滤器可以简单理解为“取你所想取”,忽视掉那些你不想要的东西;拦截器可以简单理解为“拒你所想拒”,关心你想要拒绝掉哪些东西,比如一个BBS论坛上拦截掉敏感词汇。

1.拦截器是基于java反射机制的,而过滤器是基于函数回调的。

2.过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。

3.拦截器只对action起作用,而过滤器几乎可以对所有请求起作用。

4.拦截器可以访问action上下文、值栈里的对象,而过滤器不能。

5.在action的生命周期里,拦截器可以多起调用,而过滤器只能在容器初始化时调用一次。

 

  监听器用于监听web应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。

 分类:

  按监听的对象划分,可以分为

ServletContext对象监听器

HttpSession对象监听器

ServletRequest对象监听器

 

  按监听的事件划分

对象自身的创建和销毁的监听器

对象中属性的创建和消除的监听器

session中的某个对象的状态变化的监听器

 

5. ServletContextListener:

1). what: 监听 ServletContext 对象被创建或销毁的 Servlet 监听器

 

2). how:

 

> 创建一个实现了 ServletContextListener 的类, 并且实现其中的两个方法

 

public class HelloServletContextListner implements ServletContextListener

 

> 在 web.xml 文件中配置 Listener

 

<listener> <listener-class>com.td.javaweb.test.HelloServletContextListner</listener-class>

</listener>

 

3). why: ServletContextListener 是最常用的 Listener, 可以在当前 WEB 应用被加载时对当前 WEB 应用的相关资源进行初始化操作:

创建数据库连接池, 创建 Spring 的 IOC 容器, 读取当前 WEB 应用的初始化参数 ...

 

4).API:

 

// SerlvetContext 对象被创建(即, 当前 WEB 应用被加载时)的时候, Servlet 容器调用该方法.  

public void contextInitialized(ServletContextEvent sce)

 

// SerlvetContext 对象被销毁之前(即, 当前 WEB 应用被卸载时)的时候, Servlet 容器调用该方法.

public void contextDestroyed(ServletContextEvent sce)

 

ServletContextEvent 中的: getServletContext() 获取 ServletContext

 

6. ServletRequestListener & HttpSessionListener

 

1). 和 ServletContextListener 类似。

 

2). 利用 ServletRequestListener、HttpSessionListener 以及 ServletContextListener 可以把 request, session

application 的生命周期进一步的做一了解.

 

> request: 是一个请求, 当一个响应返回时, 即被销毁. 当发送一个请求时被创建. 注意, 请求转发的过程是一个 request 对象.

重定向是两个请求

 

> session: 当第一次访问 WEB 应用的一个 JSP 或 Servlet 时, 且该 JSP 或 Servlet 中还需要创建 session 对象. 此时服务器会

创建一个 session 对象.

 

session 销毁: session 过期, 直接调用 session 的 invalidate 方法, 当前 web 应用被卸载(session 可以被持久化).

  

* 关闭浏览器, 并不意味着 session 被销毁, 还可以通过 sessionid 找到服务器中的 session 对象.  

 

JSESSIONID=F4119DE0FC93ED38E8EC83B24CFA3B81

http://localhost:8080/server/session.jsp;jsessionid=F4119DE0FC93ED38E8EC83B24CFA3B81

 

> application: 贯穿于当前的 WEB 应用的生命周期. 当前 WEB 应用被加载时创建 application 对象, 当前 WEB 应用被卸载时

销毁 application 对象.

 

7.  XxxAttributeListener

 

1). 监听 ServletContext, HttpSession, ServletRequest 中添加属性, 替换属性, 移除属性的事件监听器.

 

2). 以 ServletRequestAttributeListener 为例:

 

//添加属性时被调用

public void attributeAdded(ServletRequestAttributeEvent srae) {

System.out.println("向 request 中添加了一个属性...");

}

 

//移除属性时被调用

@Override

public void attributeRemoved(ServletRequestAttributeEvent srae) {

System.out.println("从 request 中移除了一个属性...");

}

 

//替换属性时被调用.

@Override

public void attributeReplaced(ServletRequestAttributeEvent srae) {

System.out.println("request 中属性替换了...");

}

 

3). 这三个 ServletContextAttributeListener,

ServletRequestAttributeListener, HttpSessionAttributeListener 监听器较少被使用.

 

4). API:

 

ServletRequestAttributeEvent:

 

> getName(): 获取属性的名字

> getValue(): 获取属性的值.

 

8. HttpSessionBindingListener

 

1). 监听实现了该接口的 Java 类的对象被绑定到 session 或从 session 中解除绑定的事件.

 

//当前对象被绑定到 session 时调用该方法

public void valueBound(HttpSessionBindingEvent event)

 

//当前对象从 session 中解除绑定调用该方法

public void valueUnbound(HttpSessionBindingEvent event)

 

2). 注意: 该监听器不需要在 web.xml 文件中进行配置.

 

3). HttpSessionBindingEvent:

 

getName()

getValue()

getSession()

 

4). 该监听器较少被使用.

 

9. HttpSessionActivationListener

 

1). 监听实现了该接口和 Serializable 接口的 Java 类的对象随 session 钝化和活化事件

 

> 活化: 从磁盘中读取 session 对象

 

> 钝化: 向磁盘中写入 session 对象

 

> session 对象存储在tomcat 服务器的 work\Catalina\localhost\contextPath 目录下. SESSION.SER

 

2). 该监听器不需要在 web.xml 文件中进行配置.

 

3).

//在活化之后被调用.

public void sessionDidActivate(HttpSessionEvent se)

 

//在钝化之前被调用

public void sessionWillPassivate(HttpSessionEvent se)

 

HttpSessionEvent: getSession()

 

4). 该监听器较少被使用.