学习笔记8:过滤器FIlter与监听器Listener

过滤器FIlter

通过实现一个javax.servlet.Filter的接口来实现一个过滤器,其中有三个方法,init(),doFilter(),destroy()
分别在相应的实际执行

package com.hou.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/01")   //拦截路径  拦截所有的资源路径可以使用通配符 ("/*")
public class Filter01 implements Filter {
    
    
    public void init(FilterConfig filterConfig) throws ServletException {
    
    
        
    }

    /**
     * 过滤方法
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        
        //放行资源,一定别忘了,不放行程序就不会继续往下走了
        System.out.println("filter01资源过滤----");
        filterChain.doFilter(servletRequest, servletResponse);
        
    }

    public void destroy() {
    
    

    }
}

如果有多个过滤器,形成过滤器链,则先配置的先执行。

访问权限拦截:

/**
 * 访问权限拦截
 */
@WebFilter("/*")
public class LoginAccessFilter implements Filter {
    
    
    public void init(FilterConfig filterConfig) throws ServletException {
    
    

    }

    /**
     * 功能:指定页面和请求放行,如果用户session不存在,拦截回login.jsp,如果存在,放行
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //获取请求的路径
        String uri = request.getRequestURI();
        System.out.println(uri);

		//String类 的 contains 方法可以帮助查询有没有指定的字符序列
        //如果请求路径中包含/login.jsp 这一段字符就放行
        if (uri.contains("/login.jsp") || uri.contains("loginServlet")){
    
    
            filterChain.doFilter(request,response);
            System.out.println("放行-----");
            return;
        }
        User user = (User) request.getSession().getAttribute("user");
        System.out.println(user);

        if (user != null){
    
    
            filterChain.doFilter(request,response);
            return;
        }
        //如果不是指定路径的页面或查出用户session为空代表用户没登录,那么直接跳转回login.jsp
        response.sendRedirect("login.jsp");


    }

    public void destroy() {
    
    

    }
}

监听器Listener

介绍:

web监听器是Servlet中一种特殊的类,作用是监听web中的特定事件及动作,如ServletContext ,HttpSession , ServletRequest 的创建以及销毁;或是变量的创建以及销毁、修改等。可以在动作后增加处理,实现监控。

用途例如:统计在线人数等等……

用法:实现对应的监听接口如HttpSessionListener、ServletRequestListener等……

监听Session的创建及销毁:记得加注解 @WebListener

package com.xxxx.listener;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class Listener01 implements HttpSessionListener {
    
    
    /**
     * 在Session对象被创建时执行
     * @param httpSessionEvent
     */
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
    
    
        System.out.println("监听:Session创建");
    }

    /**
     * Session对象被销毁时执行
     * @param httpSessionEvent
     */
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
    
    

        System.out.println("监听:Session销毁");
    }
}

小案例:在线人数统计

案例重点

  1. 当监听器监听到session创建的时候,代表多了一个用户,用户人数应该+1。session销毁时则相反。
  2. 因为最终数据是要返回给Servlet控制层的,所以我们要把人数信息存入 application 域中,也就是 ServletContext 域中,这样实时人数才能所有用户共享,否则如果存入session域中,那么用户只能看到截止到他那个session为止的人数。

监听器类:

package com.xxxx.listener;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
 * 实现在线人数统计
 */
@WebListener
public class OnlineListener implements HttpSessionListener {
    
    
    private Integer onlineNumber = 0;

    /**
     * 当有新的session对象创建时,人数+1
     * @param httpSessionEvent
     */
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
    
    
        onlineNumber++;
        //将更新的人数信息存如session
//        httpSessionEvent.getSession().setAttribute("onlineNumber",onlineNumber);
        httpSessionEvent.getSession().getServletContext().setAttribute("onlineNumber",onlineNumber);
    }

    /**
     * 当一个session对象销毁时,人数-1
     * @param httpSessionEvent
     */
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
    
    
        onlineNumber--;
        //将更新的人数信息存如session
//        httpSessionEvent.getSession().setAttribute("onlineNumber",onlineNumber);
        httpSessionEvent.getSession().getServletContext().setAttribute("onlineNumber",onlineNumber);
    }
}

Servlet类:

package com.xxxx.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/onlineServlet")
public class OnlineServlet extends HttpServlet {
    
    
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        HttpSession session = request.getSession();

        String key = request.getParameter("key");
        //如果传如的参数为logout,则表示退出,销毁该用户的session
        if (key != null && "logout".equals(key)){
    
    
            session.invalidate();
            return;
        }
        Integer onlineNumber = (Integer) session.getServletContext().getAttribute("onlineNumber");
        response.getWriter().write("<h2>当前在线人数:"+onlineNumber+"</h2> <a href='onlineServlet?key=logout'>退出</a>");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40492885/article/details/115314670