监听器、过滤器、拦截器,参考多篇文章整合而成,没有千篇一律的抽象回答!

18 篇文章 0 订阅
2 篇文章 0 订阅

参考文章1

一、监听器

Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener接口的服务器端程序,在javax.servlet.ServletContextListener接口中定义了2种方法。

  • void contextInitialized(ServletContextEvent sce) 监听器的初始化
  • void contextDestroyed(ServletContextEvent sce) 监听器销毁
public class ServletContextListenerUtil implements ServletContextListener{  
 
 //监听器的初始化:随web应用的启动而启动 
 @Override 
 public void contextInitialized(ServletContextEvent sce) {  
        System.out.println("监听器ServletContextListenerUtil初始化");  
    }  
 
 //监听器销毁:随web应用的停止而销毁 
 @Override 
 public void contextDestroyed(ServletContextEvent sce) {  
        System.out.println("监听器ServletContextListenerUtil销毁");  
    }  
} 

二、过滤器

Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,在javax.servlet.Filter接口中定义了3个方法:

  • void init(FilterConfig filterConfig) 用于完成过滤器的初始化
  • void destroy() 用于过滤器销毁前,完成某些资源的回收
  • void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 实现过滤功能,该方法对每个请求增加额外的处理

1. POM.xml导包

 <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.3</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>

    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.25</version>
    </dependency>

2. web.xml配置

<filter> 
 <filter-name>encodingFilter</filter-name> 
 <!-- <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> --> 
 <filter-class>com.cn.util.FilterUtil</filter-class> 
 <async-supported>true</async-supported> 
 <init-param> 
 <param-name>encoding</param-name> 
 <param-value>UTF-8</param-value> 
 </init-param> 
</filter> 
<filter-mapping> 
 <filter-name>encodingFilter</filter-name> 
 <url-pattern>/*</url-pattern> 
</filter-mapping> 

3. Filter过滤器编程

public class FilterUtil implements Filter{  
 
 @SuppressWarnings("unused")  
 private FilterConfig filterConfig; 

 //初始化:web服务器启动,就以及初始化了,随时等待过滤对象出现! 
 @Override 
 public void init(FilterConfig filterConfig) throws ServletException {  
 this.filterConfig = filterConfig;  
        System.out.println("过滤器Filter初始化");  
    }  
          //Chain : 链
          /*
          1. 过滤中的所有代码,在过滤特定请求的时候都会执行
          2. 必须要让过滤器继续同行
              chain.doFilter(request,response);
           */ 

 @Override 
 public void doFilter(ServletRequest request, ServletResponse response,  
            FilterChain chain) throws IOException, ServletException {  
 if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {  
 throw new ServletException("FilterUtil just supports HTTP requests");  
        }  
        HttpServletRequest httpRequest = (HttpServletRequest) request;  
        HttpServletResponse httpResponse = (HttpServletResponse) response;  
        httpRequest.setCharacterEncoding(this.filterConfig.getInitParameter("encoding"));  
        httpResponse.setCharacterEncoding(this.filterConfig.getInitParameter("encoding"));  
        chain.doFilter(httpRequest, httpResponse);  	//让我们的请求继续走,如果不写,程序到这里就被拦截停止!
    }  
 
 //销毁:web服务器关闭的时候,过滤器会销毁
 @Override 
 public void destroy() {  
        System.out.println("过滤器Filter销毁");  
    }  
}  

三、拦截器

在springmvc中,定义拦截器要实现HandlerInterceptor接口,并实现该接口中提供的三个方法

preHandle:原始方法调用前执行

  • 参数:
  1. request:请求对象
  2. response:响应对象
  3. handler:被调用的处理器对象
  • 返回值:
  1. 返回值为true,则执行
  2. 返回值为false,则不执行

postHandler:原始方法调用后执行

  • 参数:
  1. request:请求对象
  2. response:响应对象
  3. handler:被调用的处理器对象
  4. modelAndView:如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行跳

afterCompletion:原始方法调用完成后执行

  • 参数:
  1. request:请求对象
  2. response:响应对象
  3. handler:被调用的处理器对象
  4. ex:异常对象

1. 定义拦截器

@Component //注意当前类必须受Spring容器控制
//定义拦截器类,实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor {
     @Override
    // 原始方法调用前执行的内容
    // 返回值类型可以拦截控制的执行,true放行,false终止
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle..." + contentType);
        //获取session中的数据
        Object employee = request.getSession().getAttribute("employee");

        //若为空,不放行,且写回页面指定数据
        if (employee == null) {
            R r = R.error("NOTLOGIN");
            response.getWriter().print(JSON.toJSON(r));
            return false;
        }
        return true;
    }

    @Override
    // 原始方法调用后执行的内容
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...");
    }

    @Override
    // 原始方法调用完成后执行的内容
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}

2. 配置加载拦截器

方式一:可以继承WebMvcConfigurationSupport,但是默认静态资源路径不好使,必须重新映射

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        // 配置拦截器
        registry.addInterceptor(myInterceptor)
            .addPathPatterns("/**") // 需要拦截的路径(/** 拦截所有路径)
            .excludePathPatterns("/employee/login","/backend/**","/front/**");//放行静态资源和登陆资源;
          
    }
}

方式二:可以实现WebMvcConfigurer接口,默认静态资源路径好使.还可以重新映射

@Configuration
// 实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class MvcConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    // 拦截器 添加拦截器并设定拦截的访问路径, 路径可以通过可变参数设置多个
	/**
 	  * addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例
 	  * addPathPatterns:用于设置拦截器的过滤路径规则;addPathPatterns("/**")对所有请求都拦截
 	  * excludePathPatterns:用于设置不需要拦截的过滤规则
 	  * 拦截器主要用途:进行用户登录状态的拦截,日志的拦截等。
 	*/
    pulbic void addInterceptors(InterceptorRegistry registry) {
    	// 配置拦截器
        registry.addInterceptor(myInterceptor)
                .addPathPatterns("/**")// 需要拦截的路径(/** 拦截所有路径)
            	.excludePathPatterns("/employee/login","/backend/**","/front/**");//放行静态资源和登陆资源; 
          
    }
}

3. 新建页面的存放地点

方式一:我们可以查看WebProperties类的源码,看到静态资源可以存在于以下类路径下的几个路径中任意一个

  • /META-INF/resources/
  • /resources/
  • /static/
  • /public/

方式二:我们也可以将路径放在类路径下,通过mvc的配置类放行静态资源

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    // 拦截器 添加拦截器并设定拦截的访问路径, 路径可以通过可变参数设置多个
	/**
 	  * addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例
 	  * addPathPatterns:用于设置拦截器的过滤路径规则;addPathPatterns("/**")对所有请求都拦截
 	  * excludePathPatterns:用于设置不需要拦截的过滤规则
 	  * 拦截器主要用途:进行用户登录状态的拦截,日志的拦截等。
 	*/
    pulbic void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/employee/login","/backend/**","/front/**");//放行静态资源和登陆资源; 
    }
    
    @Override
    // 设置静态资源访问过滤,当前类需要设置为配置类,并被扫描加载
 	/**
 	  * addResoureHandler:指的是对外暴露的访问路径
 	  * addResourceLocations:指的是内部文件放置的目录
 	 */
    pulbic void addResourceHandlers(ResourceHandlerRegistry registry) {
    	// 当访问/XXX/????时候,从/xxx目录下查找内容
    	
        // 1、注册backend静态资源处理方式 **匹配多级路径
        registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
        // 2、注册front静态资源处理方式
        registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
    }
}

四、过滤器、监听器、拦截器

1. 三者作用

  • 监听器(Listener):当一个事件发生的时候,你希望获得这个事件发生的详细信息,而并不想干预这个事件本身的进程,这就要用到监听器。
  • 过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。
  • 拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。

2. 三者调用的时序(监听器、过滤器、拦截器)

  • 监听器(Listener):随web应用的启动而启动 ,随web应用的销毁而销毁,所以贯穿整个Web服务 。
  • 过滤器(Filter):首先检测URL是符合过滤器的Servlet映射,如果符合就过滤,即执行过滤器代码。所以是在进入Servlet之前。
  • 拦截器(Interceptor):preHandle、postHandler、afterCompletion方法表明,拦截器是在Servlet中执行的。

3. 三者的总结

  • 监听器:从用户访问到响应返回,整个Web服务过程。负责监听发生的事件,做出相应动作。
  • 过滤器:在进入Servlet之前,判断能不能进入Servlet。
  • 拦截器:在进入Servlet之后,对方法进行补充增强,有点像AOP

在这里插入图片描述

在这里插入图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值