过滤器&监听器
过滤器
过滤器对请求有一个拦截的作用,当请求满足我们定义的要求的时候,可以访问目标资源,不满足要求的话,不能访问目标资源
简介
-
过滤器主要用来过滤请求,是服务器的三大组件之一
-
服务器三大组件:servlet、filter、listener
-
服务器三大组件共同特点
- 都需要在web.xml中注册或写注解
- 都运行在服务器上
Filter入门使用
-
使用步骤
- 创建类实现Filter接口
- 在web.xml中注册Filter
- Tomcat启动的时候自动创建的实现类对象
import javax.servlet.*; import java.io.IOException; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/23 9:18 */ @WebFilter("/hello.jsp") public class HelloFilter implements Filter { // 初始化过滤器 @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("HelloFilter==初始化了"); } // 过滤请求的核心方法 @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("1、请求被处理"); //放行请求 filterChain.doFilter(servletRequest,servletResponse); // 服务器给浏览器作出响应时候,执行的是filterChain.doFilter System.out.println("3、服务器给浏览器作出响应"); } //过滤器销毁时调用 @Override public void destroy() { System.out.println("HelloFilter===销毁了"); } }
Filter-mapping的匹配规则
-
精确匹配
- 设置一个完整路径,只有对page.jsp发出请求的时候才会被拦截
Web.xml配置:>/page.jsp
注解配置:
- 设置一个完整路径,只有对page.jsp发出请求的时候才会被拦截
@WebFilter("/page.jsp")
- 在filter-mapping中servlet-name中设置需要拦截的serlet的名称
<filter-mapping>
<filter-name>FilterUrlPattern</filter-name>
<!--设置需要拦截的servlet的名称,往HelloServlet发出请求的时候会被拦截 -->
<servlet-name>HelloServlet</servlet-name>
</filter-mapping>
-
模糊匹配
- 前缀匹配:
/user/* 只要访问user下的资源都会被拦截 - 后缀匹配:
*.jsp 只要访问jsp文件都会被拦截 - 不合法写法:
/.jsp 或者/user/ .jsp
- 前缀匹配:
Web应用中路径问题
- "/":绝对路径
- “/"由浏览器解析代表:http://localhost:8080/ (主机地址)
a标签中的href、script标签中的src、link标签中的href、重定向、表单中的action值 - ”/“由服务器解析:由服务器解析代表:http://localhost:8080/项目名称/
转发中的地址、url-pattnts中的地址,servletContext.realPath(“/”)中的地址
监听器
简介
- Listener翻译过来叫监听器,是服务器端的三大组件之一,主要用来监听域对象的生命周期和属性的变化。
- 监听器:自己创建
- 监听的对象:ServletContext、HttpSession、ServletRequest
- 监听的事件:生命周期和属性变化
监听器分类
- 第一类生命周期:监听ServletContext、HttpSession、ServletRequest
- 第二类属性变化:ServletContext、HttpSession、ServletRequest
- 第三类:监听Session与类的关系
监听生命周期
-
ServletContext的创建与销毁
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/23 15:16 */ //监听 ServletContext创建于销毁 //@WebListener public class MyServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent servletContextEvent) { System.out.println("ServletContext创建了"); } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { System.out.println("ServletContext被销毁了"); } }-
监听结果
- tomcat启动时调用ContextInitialized方法,说明servletContext在服务器启动时被创建;
- 服务器关闭时调用contextDestroyed方法,说明服务器关闭的时候销毁了servletContext对象
-
-
ServletRequest的创建与销毁
import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/23 15:23 */ //@WebListener public class MyServletRequestListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent servletRequestEvent) { System.out.println("ServletRequest==销毁了"); } @Override public void requestInitialized(ServletRequestEvent servletRequestEvent) { System.out.println("ServletRequest==创建了"); } }- request每次请求都会创建,请求完成就销毁
-
HttpSession的创建与销毁
- 第一次访问jsp的时候会自动创建session对象,是因为jsp对应的java文件中的_jspService方法自动声明了该对象。
-
第一次访问servlet需要我们手动创建session对象才可以,即:request.getSession()
关闭服务器并且没有销毁session对象,是因为服务器关闭的时候session发生了钝化现象,即:session对象由内存被序列化到硬盘,所以没有销毁```java import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/23 15:31 */ @WebListener public class MyHttpSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent httpSessionEvent) { System.out.println("session被创建了"); } @Override public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { System.out.println("session被销毁了"); } } ```
监听属性变化
-
servletContext域中属性的变化
import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/23 15:36 */ @WebListener public class MyServletContextAttributeListener implements ServletContextAttributeListener { @Override public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("ServletContext中添加了数据"); } @Override public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("ServletContext中删除了数据"); } @Override public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("ServletContext中修改了数据"); } } -
servletRequest域中属性的变化
import javax.servlet.ServletContext; import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener; import javax.servlet.annotation.WebListener; //@WebListener public class MyServletRequestAttributeListener implements ServletRequestAttributeListener { @Override public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) { System.out.println("ServletRequest==中添加了数据"); } @Override public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) { System.out.println("ServletRequest==中删除了数据"); } @Override public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) { System.out.println("ServletRequest==中修改了数据"); } } -
HttpSession属性值变化
import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; //@WebListener public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener { @Override public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) { System.out.println("HttpSession==中添加了数据"); String name = httpSessionBindingEvent.getName(); Object value = httpSessionBindingEvent.getValue(); System.out.println(name+"---"+value); } @Override public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) { System.out.println("HttpSession==中删除了数据"); } @Override public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) { System.out.println("HttpSession==中修改了数据"); } }
监听session与类的关系
-
监听类在session中是否存在
- 当某个类实现了HttpSessionBindingListener接口,该类的对象如果存入到session中会调用valueBound方法,也就是对象被绑定到session中了。如果该类的对象从session移除了,会调用valueUnbound方法,也就是该类的对象从session中解绑了。
-
监听存在session中类的活化和钝化
- 钝化:session对象和session中保存的数据一起从内存中序列化到硬盘的过程
服务器关闭时发视钝化 - 活化:session对象和session中的数据一起从硬盘被反序列到内存的过程
服务器启动的时候发生活化 - 要保证正常的钝化和活化,session中保存的对象对应的类必须实现serializable接口
- 当某个类实现HttpSessionActivationListener接口和serializable接口后,这个类也被保存在session中了,服务器关闭的时候发生钝化现象,这个保存在session中的类的对象被序列化到硬盘上,会调用sessionWillPassvite方法;当服务再次启动的时候,发生活化现象,这个保存在session中的类对象被 反序列化到内存上,会调用sessionDidActivate方法
- 先访问BookServelt把Book对象存入session中,关闭服务器的时候,session会发生钝化,那么book对象中的sessionWillPassivate 方法会被调用;服务器再次重启的时候,服务器会被存储在磁盘中的session反序列化的内容,会相应的调用book对象中的 sessionDidActivate方法
- 钝化:session对象和session中保存的数据一起从内存中序列化到硬盘的过程

浙公网安备 33010602011771号