欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > JAVAweb之过滤器,监听器

JAVAweb之过滤器,监听器

2025/2/26 14:22:52 来源:https://blog.csdn.net/2303_80236475/article/details/145862273  浏览:    关键词:JAVAweb之过滤器,监听器

文章目录

  • 过滤器
    • 认识
    • 生命周期
    • FilterConfig
    • FilterChain
    • 过滤器执行顺序
    • 应用场景
    • 代码
  • 监听器
    • 认识
    • ServletContextListener
    • HttpSessionListener
    • ServletRequestListener
    • 代码

过滤器

认识

Java web三大组件之一,与Servlet相似。过滤器是用来拦截请求的,而非处理请求。

当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,才会接着执行用户请求的Servlet(或者接着执行其它的Filter)。

过滤器需要实现Filter接口,其源码如下:

public interface Filter {void init(FilterConfig var1) throws ServletException;void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;void destroy();
}

生命周期

  • void init(FilterConfig var1):在服务器启动时会创建Filter实例,并且每个类型的Filter只有一个实例。创建完实例后,会马上执行init()方法完成初始化工作,且这个方法只会执行一次。
  • doFilter(ServletRequest req,ServletResponse res,FilterChain chain):这个方法会在用户访问“目标资源时”(index.jsp)时执行。如果需要放行,则执行FilterChain var3的doFilter(ServletRequest,ServletResponse)方法;如果不需要放心,则不调用该方法,目标资源则无法访问。
  • destroy():服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法。

FilterConfig

Filter接口中的init()方法的参数类型为FilterConfig类型,它的功能与ServletConfig相似,与web.xml文件中的配置信息对应。下面是FilterConfig的功能介绍:

  • ServletContext getServletContext():获取ServletContext的方法;

  • String getFilterName():获取Filter的配置名称;与元素对应;

  • String getInitParameter(String name):获取Filter的初始化配置,与元素对应;

  • Enumeration getInitParameterNames():获取所有初始化参数的名称。

<filter><filter-name>FliterOne</filter-name><filter-class>com.luxiya.konghua.FliterOne</filter-class><init-param><param-name>name</param-name><param-value>luxiya</param-value></init-param><init-param><param-name>age</param-name><param-value>18</param-value></init-param>
</filter>
<filter-mapping><filter-name>FliterOne</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>public class FliterOne implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("过滤器一初始化");String filterName = filterConfig.getFilterName();System.out.println("过滤器名称:" + filterName);String name = filterConfig.getInitParameter("name");System.out.println("过滤器参数名称:" + name);Enumeration<String> names = filterConfig.getInitParameterNames();while (names.hasMoreElements()){String name = names.nextElement();String value = filterConfig.getInitParameter(name);System.out.println("元素:" + name + "  过滤器值:" + value);}}----------------结果-----------------    
过滤器一初始化
过滤器名称:FliterOne
过滤器参数名称:luxiya
元素:name  过滤器值:luxiya
元素:age  过滤器值:18

FilterChain

doFilter()方法的参数中有一个类型为FilterChain的参数,它只有一个方法:doFilter(ServletRequest,ServletResponse)。

一个目标资源上,可能部署了多个过滤器,如果当前过滤器是最后一个过滤器,那么调用chain.doFilter()方法表示执行目标资源,而不是最后一个过滤器,那么chain.doFilter()表示执行下一个过滤器的doFilter()方法。

过滤器执行顺序

  • web.xml:一个目标资源可以指定多个过滤器,过滤器的执行顺序是在web.xml文件中的部署顺序。

  • 注释:

    在 Servlet 3.0 及以上版本中,可以使用 @WebFilter 注解来配置过滤器。此时,过滤器的执行顺序由 @Order 注解或 @Priority 注解来决定。

    @Order 注解的值越小,优先级越高,过滤器会先执行;@Priority 注解的值越小,优先级也越高,过滤器先执行。

应用场景

  • 执行目标资源之前做预处理工作,例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作;

  • 通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;

  • 在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理

代码

---------------------过滤器一-------------------
public class FliterOne implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("过滤器一初始化");String filterName = filterConfig.getFilterName();System.out.println("过滤器名称:" + filterName);String root = filterConfig.getInitParameter("name");System.out.println("过滤器根路径:" + root);Enumeration<String> names = filterConfig.getInitParameterNames();while (names.hasMoreElements()){String name = names.nextElement();String value = filterConfig.getInitParameter(name);System.out.println("元素:" + name + "  过滤器值:" + value);}}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {servletRequest.setCharacterEncoding("utf-8");servletResponse.setCharacterEncoding("utf-8");servletResponse.setContentType("text/html;charset=UTF-8");System.out.println("过滤器一检测中");filterChain.doFilter(servletRequest,servletResponse);System.out.println("过滤器一检测后");}@Overridepublic void destroy() {System.out.println("过滤器一销毁");}
}
---------------------过滤器二-------------------
public class FilterTwo implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("过滤器二检测中");filterChain.doFilter(servletRequest,servletResponse);System.out.println("过滤器二检测后");}@Overridepublic void destroy() {}
}
---------------------web.xml-------------------<filter><filter-name>FliterOne</filter-name><filter-class>com.luxiya.konghua.FliterOne</filter-class><init-param><param-name>name</param-name><param-value>luxiya</param-value></init-param><init-param><param-name>age</param-name><param-value>18</param-value></init-param></filter><filter-mapping><filter-name>FliterOne</filter-name><url-pattern>/*</url-pattern></filter-mapping><filter><filter-name>FilterTwo</filter-name><filter-class>com.luxiya.konghua.FilterTwo</filter-class></filter><filter-mapping><filter-name>FilterTwo</filter-name><url-pattern>/*</url-pattern></filter-mapping>---------------------结果-------------------
过滤器一初始化
过滤器名称:FliterOne
过滤器根路径:luxiya
元素:name  过滤器值:luxiya
元素:age  过滤器值:18过滤器一检测中
过滤器二检测中Hello Servlet,我执行了HelloServlet过滤器二检测后
过滤器一检测后

监听器

认识

在JavaWeb被监听的事件源为:ServletContext、HttpSession、ServletRequest,即三大域对象。

  • 监听域对象“创建”与“销毁”的监听器;

  • 监听域对象“操作域属性”的监听器;

  • 监听HttpSession的监听器。

ServletContextListener

ServletContextListener:Tomcat启动和关闭时调用下面两个方法:

  • public void contextInitialized(ServletContextEvent evt):ServletContext对象被创建后调用;

  • public void contextDestroyed(ServletContextEvent evt):ServletContext对象被销毁前调用;

HttpSessionListener

HttpSessionListener:开始会话和结束会话时调用下面两个方法

  • public void sessionCreated(HttpSessionEvent evt):HttpSession对象被创建后调用;

  • public void sessionDestroyed(HttpSessionEvent evt):HttpSession对象被销毁前调用;

ServletRequestListener

ServletRequestListener:开始请求和结束请求时调用下面两个方法

  • public void requestInitiallized(ServletRequestEvent evt):ServletRequest对象被创建后调用;

  • public void requestDestroyed(ServletRequestEvent evt):ServletRequest对象被销毁前调用。

代码

public class Listener implements ServletContextListener, HttpSessionListener, ServletRequestListener {@Overridepublic void contextInitialized(ServletContextEvent servletContextEvent) {System.out.println("监听器初始化---ServletContext对象被创建后调用");}@Overridepublic void contextDestroyed(ServletContextEvent servletContextEvent) {System.out.println("监听器销毁---ServletContext对象被销毁后调用");}@Overridepublic void requestDestroyed(ServletRequestEvent servletRequestEvent) {System.out.println("监听器销毁---ServletRequest对象被销毁后调用");}@Overridepublic void requestInitialized(ServletRequestEvent servletRequestEvent) {System.out.println("监听器初始化---ServletRequest对象被创建后调用");}@Overridepublic void sessionCreated(HttpSessionEvent httpSessionEvent) {System.out.println("监听器初始化---HttpSession对象被创建后调用");}@Overridepublic void sessionDestroyed(HttpSessionEvent httpSessionEvent) {System.out.println("监听器销毁---HttpSession对象被销毁后调用");}
}
-------------------结果----------------
监听器初始化---ServletContext对象被创建后调用
过滤器一初始化
过滤器名称:FliterOne
过滤器根路径:luxiya
元素:name  过滤器值:luxiya
元素:age  过滤器值:18
[2025-02-25 08:31:10,220] Artifact fliter_listener:war exploded: Artifact is deployed successfully
[2025-02-25 08:31:10,220] Artifact fliter_listener:war exploded: Deploy took 226 milliseconds
监听器初始化---ServletRequest对象被创建后调用
过滤器一检测中
过滤器二检测中
监听器初始化---HttpSession对象被创建后调用(第一次请求才有)
Hello Servlet,我执行了HelloServlet
过滤器二检测后
过滤器一检测后
监听器销毁---ServletRequest对象被销毁后调用

统计网站人数例子

//统计网站在线人数 : 统计session
public class OnlineCountListener implements HttpSessionListener {//创建session监听: 看你的一举一动//一旦创建Session就会触发一次这个事件!public void sessionCreated(HttpSessionEvent se) {ServletContext ctx = se.getSession().getServletContext();System.out.println(se.getSession().getId());Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");if (onlineCount==null){onlineCount = new Integer(1);}else {int count = onlineCount.intValue();onlineCount = new Integer(count+1);}ctx.setAttribute("OnlineCount",onlineCount);}//销毁session监听//一旦销毁Session就会触发一次这个事件!public void sessionDestroyed(HttpSessionEvent se) {ServletContext ctx = se.getSession().getServletContext();Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");if (onlineCount==null){onlineCount = new Integer(0);}else {int count = onlineCount.intValue();onlineCount = new Integer(count-1);}ctx.setAttribute("OnlineCount",onlineCount);}/*Session销毁:1. 手动销毁  getSession().invalidate();2. 自动销毁*/
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词