Filter+Listener

文章目录

      • 1. Filter
        • 1.1 Filter快速入门
        • 1.2 Filter执行流程
        • 1.3 Filter拦截路径
        • 1.4 案例
      • 2. Listener

JavaWeb 三大组件

  • Servlet
    Servlet 是在服务器端执行的 Java 类,用于处理客户端请求和生成响应。它可以接收HTTP请求并返回HTTP响应,通常用于处理Web应用程序的业务逻辑。Servlet 运行在 Servlet 容器中,如 Tomcat 或 Jetty。
  • Filter
    过滤器是一种用于在请求到达 Servlet 之前或响应回传给客户端之前修改请求和响应的组件。它可以对请求进行预处理、过滤和修改,并对响应进行后处理。过滤器可以用于实现身份验证、日志记录、字符编码转换等功能,以及对请求和响应进行过滤与增强。
  • Listener
    监听器用于监听 Web 应用程序中的事件和状态变化,并在事件发生时执行相应的操作。常见的监听器包括 ServletContextListener(监听 Servlet 上下文的创建和销毁)、HttpSessionListener(监听会话的创建和销毁)和 ServletRequestListener(监听请求的创建和销毁)等。监听器可以用于执行初始化操作、资源管理、应用程序监控等。

1. Filter

过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。

  • 如下图所示,浏览器可以访问服务器上的所有的资源(servlet、jsp、html等)
  • 而在访问到这些资源之前可以使过滤器拦截来下,也就是说在访问资源之前会先经过 Filter
    Filter+Listener_第1张图片

应用场景

  1. 身份验证和授权
    过滤器可用于验证用户身份和权限。它可以拦截请求,检查用户是否已登录或是否具有访问特定资源的权限。如果用户未经身份验证或权限不足,过滤器可以重定向到登录页面或返回相应的错误信息。
  2. 请求参数处理
    过滤器可以对请求参数进行预处理和验证。它可以检查请求参数的完整性、格式和有效性,并根据需要进行转换或修正。
  3. 日志记录和统计
    过滤器可以用于记录请求和响应的日志,以及收集应用程序的统计数据。
  4. 缓存和性能优化:
    过滤器可用于缓存静态内容或动态内容的部分结果,以提高应用程序的性能和响应速度。
  5. 异常处理:
    过滤器可以捕获并处理请求处理过程中的异常。它可以拦截异常,并根据需要生成适当的错误响应或执行特定的异常处理逻辑。

1.1 Filter快速入门

步骤:

  1. 定义类,实现Filter接口,重写其方法;
  2. 配置Filter拦截资源的路径:在类上定义 @WebFilter 注解。而注解的 value 属性值 /* 表示拦截所有的资源
  3. 在doFilter方法中输出一句话,并放行
package com.filter;


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

//2. 定义拦截路径
@WebFilter("/*")
public class FilterDemo1 implements Filter {

    //1.重写Filter接口中的三个方法
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filter 被执行 FilterDemo1。。。。");

        //放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

Filter+Listener_第2张图片

1.2 Filter执行流程

Filter+Listener_第3张图片

Filter过滤器链

  1. 执行 Filter1 的放行前逻辑代码
  2. 执行 Filter1 的放行代码
  3. 执行 Filter2 的放行前逻辑代码
  4. 执行 Filter2 的放行代码
  5. 访问到资源
  6. 执行 Filter2 的放行后逻辑代码
  7. 执行 Filter1 的放行后逻辑代码

Filter+Listener_第4张图片

1.3 Filter拦截路径

  • 拦截具体的资源:/index.jsp:只有访问index.jsp时才会被拦截
  • 目录拦截:/user/*:访问/user下的所有资源,都会被拦截
  • 后缀名拦截:*.jsp:访问后缀名为jsp的资源,都会被拦截
  • 拦截所有:/*:访问所有资源,都会被拦截

1.4 案例

访问服务器资源时,需要先进行登录验证,如果没有登录,则自动跳转到登录页面。
Filter+Listener_第5张图片

1.创建名为 LoginFilter 的过滤器

@WebFilter("/*")
public class LoginFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
      
    }

    public void init(FilterConfig config) throws ServletException {
    }

    public void destroy() {
    }
}

完成以下逻辑

  • 获取Session对象
  • 从Session对象中获取名为 user 的数据
  • 判断获取到的数据是否是 null * 如果不是,说明已经登陆,放行 * 如果是,说明尚未登陆,将提示信息存储到域对象中并跳转到登陆页面
package com.filter;


import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

//2. 定义拦截路径
@WebFilter("/*")
public class LoginFilter implements Filter {

    //1.重写Filter接口中的三个方法
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        //1. 判断session中是否有user
        HttpSession session = req.getSession();
        Object user = session.getAttribute("user");

        //2. 判断user是否为null
        if(user != null){
            // 登录过了
            //放行
            filterChain.doFilter(req, servletResponse);
        }else {
            // 没有登陆,存储提示信息,跳转到登录页面

            req.setAttribute("login_msg","您尚未登陆!");
            req.getRequestDispatcher("/login.jsp").forward(req,servletResponse);
        }
    }

    @Override
    public void destroy() {

    }
}

Filter+Listener_第6张图片
判断session中是否包含用户信息之前,应该加上对登陆及注册相关资源放行的逻辑处理

//判断访问资源路径是否和登录注册相关
//1,在数组中存储登陆和注册相关的资源路径
String[] urls = {"/login.jsp","/imgs/","/css/","/loginServlet","/register.jsp","/registerServlet","/checkCodeServlet"};
//2,获取当前访问的资源路径
String url = req.getRequestURL().toString(); 

//3,遍历数组,获取到每一个需要放行的资源路径
for (String u : urls) {
    //4,判断当前访问的资源路径字符串是否包含要放行的的资源路径字符串
    /*
    	比如当前访问的资源路径是  /brand-demo/login.jsp
    	而字符串 /brand-demo/login.jsp 包含了  字符串 /login.jsp ,所以这个字符串就需要放行
    */
    if(url.contains(u)){
        //找到了,放行
        chain.doFilter(request, response);
        //break;
        return;
    }
}

2. Listener

监听器可以监听就是在 applicationsessionrequest 三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。

你可能感兴趣的:(java,tomcat)