一文搞懂过滤器,拦截器和监听器的区别和使用

一.过滤器

     1.什么是过滤器

             过滤器(Filter)依赖于servlet容器,是实现了javax.servlet.Filter接口的程序,基于函数回调,主要可以过滤字符编码,做一些业务逻辑判断,比如token验证,用户是否登录等等。当在web.xml中配置好要拦截的客户端请求,就会对拦截的请求进行处理。它是随着web应用的启动而启动的,只初始化一次,当应用停止或重新部署才会销毁。
 

      2.过滤器中的方法

            void  init(FilterConfig filterConfig)      用于完成过滤器的初始化。
           void  doFilter(ServletRequest request,ServletResponse response,FilterChain chain)    实现过滤功能,该方法对每个请求增加额外处理,主要处理方法
                    在doFilter方法中 chain.doFilter(request, response);//需要放行时,需要调用FilterChain的doFilter方法。
           void  destroy()         用于过滤器销毁前,完成某些资源的回收。
     

      3.过滤器案例

            过滤器类需要实现Filter接口
public class HelloFilter implements Filter{
      public void destroy() {
      }
      public void doFilter(ServletRequest request, ServletResponse response,
                  FilterChain chain) throws IOException, ServletException {
            //用到session,需要先强转http标准
            HttpServletRequest req=(HttpServletRequest)request;
            if(req.getSession().getAttribute("admin")==null){
                  response.setContentType("text/html;charset=utf-8");
                  response.getWriter().println("<script type='text/javascript'>alert('请登录后操作!');location='../index.jsp';</script>");
            }else{
                  chain.doFilter(request, response);
            }
      }
      public void init(FilterConfig arg0) throws ServletException {
      }
}

         在web.xml中需要配置,哪些请求被过滤,以及指定哪个过滤器处理

<!-- 配置过滤器 -->
<filter><!-- 注册过滤器 -->
<filter-name>HelloFilter</filter-name>
<filter-class>filter.HelloFilter</filter-class>
</filter>
<filter-mapping><!-- 配置哪些请求需要过滤 -->
<filter-name>HelloFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

       4.多个过滤器的执行顺序跟xml中定义的先后关系有关。

 

二.拦截器

        1. 什么是拦截器    

                  拦截器(Interceptor):依赖于web框架,实现了HandlerInterceptor接口。在springmvc中就是依赖于springmvc框架,基于java的反射机制,属于aop的一种应用。在你的service或者调用一个方法前,后或抛出异常时做相应的逻辑操作。拦截器可以使用依赖注入来执行一些业务操作,同时一个拦截器可以在一个controller生命周期中多次调用。
 

        2.拦截器中的方法

               preHandle方法:进入Handler方法之前执行,可用于身份验证,没有登陆返回false不往下执行,否则返回true.
               postHandle方法:进入Handler方法之后,返回ModelAndView之前执行。该方法中又ModelAndView的形参。 
               afterCompletion方法:执行完Handler之后执行。比如统一日志处理等。
 

       3.拦截器的案例

public class InterceptorUtil implements HandlerInterceptor{  
//进入Handler方法之前执行
//可以用于身份认证、身份授权。如果认证没有通过表示用户没有登陆,需要此方法拦截不再往下执行,否则就放行
@Override
public boolean preHandle(HttpServletRequest request,  
            HttpServletResponse response, Object handler) throws Exception {  

        System.out.println("InterceptorUtil...........preHandle");  
        String user= (String) request.getSession().getAttribute("user");  
        if(user != null){  
          return true;  
        }  
        request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);  
        //true表示放行,false表示不放行
        return false;  
    }  
@Override
public void postHandle(HttpServletRequest request,  
            HttpServletResponse response, Object handler,  
            ModelAndView modelAndView) throws Exception {  
// TODO Auto-generated method stub
        System.out.println("InterceptorUtil...........postHandle");  
    }  
@Override
public void afterCompletion(HttpServletRequest request,  
            HttpServletResponse response, Object handler, Exception ex)  
throws Exception {  
// TODO Auto-generated method stub
        System.out.println("InterceptorUtil...........afterCompletion");  
    }  
}  

          在springmvc.xml或者structs.xml配置文件中:

<!-- 拦截器配置 -->
<mvc:interceptors>
<!--多个拦截器,顺序执行 -->
<!-- 登陆认证拦截器 -->
<mvc:interceptor>
<!-- /** 表示拦截所有url包括子url路径,/*只拦截根下的url -->
<mvc:mapping path="/**"/>
<bean class="com.cn.util.InterceptorUtil"></bean>
</mvc:interceptor>
<!-- 其他拦截器 -->
</mvc:interceptors>

 

三.过滤器与拦截器比较

   1.两者的区别

  • 过滤器是基于函数回调,拦截器是基于反射机制。
  • 过滤器依赖于servlet容器,拦截器依赖于web容器
  • 过滤器可以对几乎所有请求起作用,拦截器只对action请求起作用
  • 过滤器不能访问action的上下文和值栈中的对象,拦截器可以
  • 过滤器在servlet容器初始化时被调用一次,拦截器可以被多次调用
 

   2.两者的使用场景

  • 过滤器(Filter):当你有一堆东西时,你只希望选择符合你要求的一些东西,定义这些要求的工具就是过滤器。

  • 拦截器(Interceptor):在一个流程正在进行时,你希望干预他的进展,甚至终止他的进行,可以用到拦截器
 

   3.两者的执行顺序

 

四.监听器

    1.什么是监听器

          监听器用于监听web应用中的某些对象,信息的创建,销毁,增加,修改,删除等动作的发生,然后做出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。此技术常用在统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等。
 

    2.监听器实例

         监听在线人员
         实现思路:在application启动时,放入List存放在线人员名单,在sessionsetAttribute时,向List中添加信 息放入app,session销毁时,向List中信息移除后再放入app
public class OnlineListener implements ServletContextListener,HttpSessionAttributeListener,HttpSessionListener{
    private ServletContext application=null;
    public void contextDestroyed(ServletContextEvent arg0) {
    }
    //在application启动时,放入List存放在线人员名单
    public void contextInitialized(ServletContextEvent sce) {
        List users=new ArrayList();
        application=sce.getServletContext();
        application.setAttribute("users", users);
    }
    //在sessionsetAttribute时,向List中添加信息放入app
    public void attributeAdded(HttpSessionBindingEvent hsbe) {
        List users=(List)application.getAttribute("users");
        String username=(String)hsbe.getValue();
        users.add(username);
        application.setAttribute("users", users);
    }
    public void attributeRemoved(HttpSessionBindingEvent arg0) {
    }
    public void attributeReplaced(HttpSessionBindingEvent arg0) {
    }
    public void sessionCreated(HttpSessionEvent arg0) {
    }
    //session销毁时,将List中信息移除后再放入app
    public void sessionDestroyed(HttpSessionEvent hse) {
        List users=(List)application.getAttribute("users");
        //取出当前销毁的session中的username
        String username=(String)hse.getSession().getAttribute("username");
        users.remove(username);
        application.setAttribute("users", users);        
    }
}

         注册监听器:

<listener>
            <listener-class>listener.OnlineListener</listener-class>
</listener>

       在web-xml中配置时,要注意配置文件的顺序:监听器--》过滤器--》servlet。

 

五.springboot中的监听器,过滤器和拦截器的使用

       1.监听器的注册

@Configuration
public class ListenerConfig {
    // 这里会直接注入
    @Bean
    public StartupListener startupListener() {
        return new StartupListener();
    }

            2.拦截器的注册

@Configuration
public class MvcConfig implements WebMvcConfigurer {


    /**
     * 注册配置的拦截器
     * @param registry 拦截器注册器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 这里的拦截器是new出来的,在Spring框架中可以交给IOC进行依赖注入,直接使用@Autowired注入
        registry.addInterceptor(new UrlInterceptor());
    }
}
//使用自动注入的方式注入拦截器,添加应用、或不应用该拦截器的URI(addPathPatterns/excludePathPatterns)
// addPathPatterns 用于添加拦截的规则,excludePathPatterns 用于排除拦截的规则
registry.addInterceptor(urlInterceptor).addPathPatterns(new UrlInterceptor()).excludePathPatterns("/login")

                    3.过滤器的注册


@Order(2) 
@WebFilter(urlPatterns = {"/user/*"}, filterName = "loginFilter")
public class SessionFilter implements Filter {

}
上述的配置中,头部的有两个注解:

@Order注解: 用于标注优先级,数值越小优先级越大;
@WebFilter注解: 用于标注过滤器,urlPatterns指定过滤的URI(多个URI之间用逗号分隔),filterName指定名字;
注: 使用@WebFilter注解,必须在Springboot启动类上加@ServletComponentScan注解,否则该注解不生效,过滤器无效!
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean registFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new UrlInterceptor()());
        registration.addUrlPatterns("/*");
        registration.setName("CostTimeFilter");
        registration.setOrder(1);
        return registration;
    }
}

  springboot中的监听器,过滤器和拦截器的使用详细可参考博文:https://blog.csdn.net/jacksonary/article/details/84572701

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值