java servlet 监听_第三十六天JavaWeb-Servlet中的监听器和过滤器

本文详细介绍了Servlet中的过滤器和监听器。过滤器在请求到达Servlet之前执行,常用于统一设置字符集和拦截URL。创建过滤器需要实现Filter接口并配置于web.xml。监听器则监听特定事件,如application、session和request对象的创建与销毁,属性的添加、删除和替换。监听器的应用场景包括统计在线人数等。
摘要由CSDN通过智能技术生成

Servlet中的过滤器和监听器

一、过滤器

过滤器:顾名思义就是要起到过滤的作用。所有的请求在真正到达servlet之前都会先经过过滤器过滤一遍。过滤器也是Servlet的一种,因此也有init和destroy方法,还有一个服务方法,只是这里提供的服务是过滤。

一般客户端发出请求以后会交给Servlet,如果过滤器的存在,则客户端发出的请求都是先交给过滤器处理之后,再交给Servlet去处理对应的业务逻辑。

一、创建过滤器的步骤

​ 1.实现javax.servlet.Filter接口。

​ 2.实现Filter接口中的三个方法:init、doFilter、destroy。

​ 3.在web.xml中配置,让服务器知道过滤器的存在,否则是没有用的。

public class MyFilter implements Filter {

@Override

public void destroy() {

}

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

//放行请求 chain.doFilter(req, response);

}

@Override

public void init(FilterConfig filterConfig) throws ServletException {

}

}

MyFilter

com.zk.filter.MyFilter

MyFilter

/*

​ 写的是该过滤器类的名字,可以随意写。

​ 写的是实现Filter接口的子类全路径名。

​ 表示的是拦截的范围

​ 过滤器拦截范围:

​ 1.拦截所有 /*

​ 2.拦截部分servlet请求 拦截请求的结尾 eg: .do /.action

​ 3.拦截执行servlet请求 /指定的名字

介绍一下实现Filter接口的三个方法:

​ init()方法:服务器启动的时候就会调用,只会执行一次,在服务器启动的时候就会初始化。

​ doFilter()方法: 服务器在接收到浏览器发过来的请求后,先解析请求信息,创建对象request和response然后根据请求URL地址判断如果符合过滤器的过滤范围,则会调用过滤器中的doFilter来进行请求拦截,并将request和response对象作为实参传递给doFilter方法。可以在doFilter方法中声明过滤器拦截代码。 每次拦截请求都会调用。

destroy()方法:销毁方法,服务器自动调用,只会执行一次,在服务器关闭的时候触发。

过滤器链:

​ 当web.xml中配置有多过滤器时,服务器会根据wem.xml中配置的顺序从上到下执行,谁先配置谁先执行,放行时,如果有下一个过滤器,会自动的放行到下一个过滤器,如果没有则放行到指定的资源。

过滤器可以用来干什么呢? 两个简单的应用:

1.统一设置字符集

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

request.setCharacterEncoding("utf-8");

response.setCharacterEncoding("utf-8");

response.setContentType("text/html;charset=utf-8");

}

​ 再也不用担心中文乱码的问题了。

2.拦截URL,不登录不允许直接访问页面。

​ 配合session对象,检测,如果用户登录进入页面,则在session中设置一个属性,在doFilter方法进行进行获取,如果为null,则重定向到登陆页面,再次过程中会将登录界面不做拦截,要不然就会陷入无限的死循环。

注:使用servlet3.0时,可以不需要在web.xml中配置,直接可以使用注解

可通过自带的servlet软件创建(listener和filter也都可以这么做)

@WebServlet("/s01") //可随意自定资源名public class Servlet01 extends HttpServlet {

private static final long serialVersionUID = 1L;

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

System.out.println("Servlet01...");

}

}

自定义资源名建议和类同名,以见名知到是哪一个Servlet类。

二、监听器

​ 监听器顾名思义就是监听某种事件的发生,即当某个事件发生时,就触发了某个设置好的监听器,但是这里触发的原因不同。例如地震监测仪监听地震的发生,大气检测仪,检测空气的变化以提供预警。

​ 在Servlet中因监听对象的不同分为不同的监听器,这里指定的监听对象是application、session对象,request对象,每个对象都有各自的监听器。

实现监听的步骤:

​ 1.继承相关对象对应的接口

//监听request对象的接口,和监听request对象属性接口ServletRequestListener, ServletRequestAttributeListener

//监听Session对象的接口,和监听Session对象属性接口HttpSessionListener,HttpSessionAttributeListener

//监听application对象的接口,和监听application对象属性接口ServletContextListener,ServletContextAttributeListener

​ 2.在web.xml中配置实现该接口的子类信息,一个实现类,写一个标签,在中只能写一个。在servlet3.0以上也可以使用注解代替xml中的配置。后面的例子中可见。

com.zk.listener.MyListener2

​ 示例

package com.zk.listener;

import javax.servlet.*;

import javax.servlet.annotation.WebListener;

import javax.servlet.http.*;

/*** @author zk* @title: MyListener* @projectName ListenerAndFilter* @description: TODO* @date 2019/8/28 9:17*/

//@WebListener("/myListener")public class MyListener implements ServletRequestListener, ServletRequestAttributeListener, HttpSessionListener, HttpSessionAttributeListener, ServletContextListener,ServletContextAttributeListener {

@Override

public void requestDestroyed(ServletRequestEvent sre) {

System.out.println("request对象被销毁了");

}

@Override

public void requestInitialized(ServletRequestEvent sre) {

System.out.println("request对象被创建了");

}

@Override

public void attributeAdded(ServletRequestAttributeEvent srae) {

//获取request设置的键和值 System.out.println(srae.getName() + "...." + srae.getValue());

}

@Override

public void attributeRemoved(ServletRequestAttributeEvent srae) {

//获取request移除的键和值 System.out.println(srae.getName() + "...." + srae.getValue());

}

@Override

public void attributeReplaced(ServletRequestAttributeEvent srae) {

//获取request替换的键和值 System.out.println(srae.getName() + "...." + srae.getValue());

}

@Override

public void sessionCreated(HttpSessionEvent se) {

System.out.println("session对象被创建");

}

@Override

public void sessionDestroyed(HttpSessionEvent se) {

System.out.println("session对象被销毁");

}

@Override

public void attributeAdded(HttpSessionBindingEvent se) {

HttpSession session = se.getSession();

System.out.println(se.getName() + "...." + se.getValue());

}

@Override

public void attributeRemoved(HttpSessionBindingEvent se) {

HttpSession session = se.getSession();

System.out.println(se.getName() + "...." + se.getValue());

}

@Override

public void attributeReplaced(HttpSessionBindingEvent se) {

HttpSession session = se.getSession();

System.out.println(se.getName() + "...." + se.getValue());

}

@Override

public void attributeAdded(ServletContextAttributeEvent scae) {

System.out.println(scae.getName() + "...." + scae.getValue());

}

@Override

public void attributeRemoved(ServletContextAttributeEvent scae) {

System.out.println(scae.getName() + "...." + scae.getValue());

}

@Override

public void attributeReplaced(ServletContextAttributeEvent scae) {

System.out.println(scae.getName() + "...." + scae.getValue());

}

@Override

public void contextInitialized(ServletContextEvent sce) {

System.out.println("ServletContext对象被创建");

System.out.println("ServletContext对象:"+ sce.getServletContext());

}

@Override

public void contextDestroyed(ServletContextEvent sce) {

System.out.println("ServletContext对象被销毁");

}

}

​ 1.application监听器:ServletContextListener

​ public void contextInitialized(ServletContextEvent sce); //在application创建时被调用

​ public void contextDestroyed(ServletContextEvent sce);//在application对象被销毁时调用

方法中的参数都可以获取监听application对象

​ 2.application属性监听器:ServletContextAttributeListener

​ 需要实现的方法:

​ public void attributeAdded(ServletContextAttributeEvent e); //当调用application.setAttribute()时调用

​ public void attributeRemoved(ServletContextAttributeEvent e); //当调用applcaition.removeAttribute()时调用

​ public void attributeReplaced(ServletContextAttributeEvent e); //当调用两次application.setAttribute()赋予相同属性时调用

参数ServletContextAttributeEvent可以获得触发该监听器的属性名称和属性值,方法有:

(1)getName(); 取得属性的名称;

(2)getValue(); 取得属性的值;(注意:返回的是Object,必须转型)

​ 3.Session对象监听器:HttpSessionListener

​ 需要实现的方法:

​ public void sessionCreated(HttpSessionEvent e); //当打开一个浏览器时,就会触发这个方法

​ public void sessionDestroyed(HttpSessionEvent e);//当调用session.invalidate()时,或超时掉哦那个HttpSessionEvent的方法getSession()获取触发监听器的session对象。

4.session属性监听器:HttpSessionAttributeListener

​ 需要实现的方法:

​ public void attributeAdded(HttpSessionBindingEvent e); //当调用session.setAttribute()时调用

​ public void attributeRemoved(HttpSessionBindingEvent e);//当调用session.removeAttribute()时调用

public void attributeReplaced(**HttpSessionBindingEvent** e);//当调用两次session.setAttribute()赋予同一个属性对应的value时,该方法被触发调用。

属性时调用

HttpSessionBindingEvent 方法:

(1)getSession();//获取触发监听器的session

(2)getName();//获取属性名称

(3)getValue();//获取属性值

监听器应用的场景

​ ServletContextListener: 在任何Servlet提供服务之前执行、在Servlet销毁时执行,用于提前初始化一些资源,比如数据库的连接、销毁一些资源,比如数据库的连接:

ServletContextAttributeListener:上下文中添加、删除、替换了属性;

HttpSessionListener:多少个在线用户,即跟踪会话;

HttpSessionAttributeListener:会话属性添加、删除、替换;

案例:统计网站的在线人数

可以通过HttpSessionListener来监听session对象的变化,首先通过ServletContextListener监听,当服务器启动时,在contextInitialized方法中创建一个统计的标志count,将它设置进入ServletContext对象的域中,每当有session被创建出来count就自增1,在sessionCreated方法中通过监听到的新生session对象获取到ServletContext对象,把count值设置进入ServletContext域中,当有session销毁或者session时间超时时,通过sessionDestroyed方法获取销毁的session对象,通过该session对象获得ServletContext对象,把count自减一后设置入ServletContext对象的域中,这个页面就可以获得试试在线人数了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值