过滤器、监听器、拦截器的使用

过滤器 监听器 拦截器
关注的点 web请求 系统级别的参数 Action
如何实现 函数回调 事件 java反射机制(动态代理)
应用场景 设置字符编码,URL级别的权限控制访问 统计网站在线人数 拦截未登录用户
是否依赖servlet容器

过滤器

主要针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验
它依赖于servlet容器。在实现上,基于函数回调,它可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据,比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。通常用的场景是:在过滤器中修改字符编码(CharacterEncodingFilter)、在过滤器中修改HttpServletRequest的一些参数(XSSFilter(自定义过滤器)),如:过滤低俗文字、危险字符等

自定义过滤器实现javax.servlet包下的Filter接口,并重写doFilter方法

package com.sansux.Filter_Listener_interceptor;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

/**
 * Created by zhouhaihua on 2018/9/23
 */
public class AuthFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("authFilter 开始工作··");
        chain.doFilter(request,response); // 继续执行后续操作
    }

    @Override
    public void destroy() {

    }
}

web.xml中的配置

<filter>
        <filter-name>authFilter</filter-name>
        <filter-class>com.sansux.Filter_Listener_intecerptor.AuthFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>authFilter</filter-name>
        <url-pattern>/</url-pattern>
    </filter-mapping>

拦截器

拦截器的配置一般在SpringMVC的配置文件中,使用Interceptors标签,
拦截器是基于java反射机制的,属于面向切面编程的一种运用,可以使用spring的依赖注入进行业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller进行拦截,对其他一些静态资源则无法进行拦截处理

Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。
要使用Spring MVC中的拦截器,就需要对拦截器类进行定义和配置。通常拦截器类可以通过两种方式来定义。
1.通过实现HandlerInterceptor接口,或继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来定义。

2.通过实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类来定义。

以实现HandlerInterceptor为例

package com.sansux.Filter_Listener_interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by zhouhaihua on 2018/9/23
 */
public class CustomInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

上述代码中,自定义拦截器实现了HandlerInterceptor接口,并实现了接口中的三个方法:

preHandle() 方法:该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;
当其返回值为false时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行等)。

postHandle()方法:该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。

afterCompletion()方法:该方法会在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。

mvc.xml中的配置

<mvc:interceptors>
        <!--<bean class="com.sansux.Filter_Listener_interceptor.CustomeInterceptor" />-->
        <!--拦截器1-->
        <mvc:interceptor>
            <!--配置拦截器的作用路径-->
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path=""/>
            <!--定义在<mvc:interceptor>下面的表示匹配指定路径的请求才进行拦截-->
            <bean class="com.sansux.Filter_Listener_interceptor.Intercptor1"/>
        </mvc:interceptor>
        <!--拦截器2-->
        <mvc:interceptor>
            <mvc:mapping path="/hello"/>
            <bean class="com.sansux.Filter_Listener_interceptor.Interceptor2"/>
        </mvc:interceptor>

二者的区别

  1. 使用范围不同
    Filter是Servlet规范规定的,只能用于web程序中,而拦截器可以用于web程序、Application和swing
  2. 规范不同
    Filter在servlet中定义,是servlet容器支持的,而拦截器是spring框架支持的
  3. 使用的资源不同(拦截器可以访问action上下文、值栈里的对象,而过滤器不能。)
    拦截器也是spring的一个组件,归spring容器管理,配置在spring文件中,因此能使用spring中的任何资源、对象。例如service、对象、数据源、事务管理等,通过Ioc注册到拦截器
  4. 深度不同
    Filter只在Servlet前后起作用,而拦截器能够深入到方法前后、异常抛出前后,因此拦截器具有更大的弹性,在spring结构的程序中,优先使用拦截器
  5. 拦截器基于jdk反射(动态代理),过滤器是基于函数回调
  6. 拦截器只对action起作用,过滤器可以对几乎所有请求起作用

监听器

javaweb共有八类监听器,分为三类

  1. 用来监听三大作用域的创建和销毁的监听器
    ServletContextListener(接口) 用来监听ServletContext对象创建和销毁的监听器
    创建:服务器启动,web应用加载后立即创建代表当前web应用的ServletContext对象
    销毁:服务器关闭或web应用被移除出容器时,随着web应用的销毁而销毁
    HttpSessionListener(接口) 用来监听HttpSession对象创建和销毁的监听器
    创建:第一次调用request.getSession方法时创建代表当前会话的session对象
    销毁:超过30分钟没人用销毁/调用invalidate方法自杀/服务器非正常关闭时随着web应用的销毁而销毁,如果服务器是正常关闭会被钝化起来.

    当服务器正常关闭时,还存活着的session会随着服务器的关闭被以文件的形式存储在tomcat的work目录下,这个过程叫做session的钝化
    当服务器再次正常开启时,服务器会找到之前的SESSIONS.ser文件从中恢复之前保存起来的session对象这个过程叫做session的活化
    想要随着Session被钝化活化的对象它的类必须实现Serializable接口

    ServletRequestListener(接口) 用来监听ServletRequest对象创建和销毁的监听
    创建:请求开始创建代表请求的request对象
    销毁:请求结束时代表请求的request对象销毁

  2. 用来监听三大作用域中属性变化的监听器
    ServletContextAttributeListener(接口)
    HttpSessionAttributeListener (接口)
    ServletRequestAttributeListener(接口)

  3. 使javabean自己感知自己在Session中状态变化的监听器,这两个监听器很特殊,不需要自己去写类实现也不需要在web.xml中注册,只要使javabean实现这个接口就能起作用
    HttpSessionBindingListener(接口)
    javabean被绑定到session中
    sessionDidActive(HttpSessionBindingEvent event)
    javabean被移除绑定从session中
    valueUnbound(HttpSessionBindingEvent event)方法

    HttpSessionActivationListener (接口)
    javabean随着session被钝化
    sessionWillPassivate(HttpSessionBindingEvent event)
    javabean随着session被活化
    sessionDidActive(HttpSessionBindingEvent event)

HttpSessionListeners

public interface HttpSessionListener extends EventListener {
    
    public void sessionCreated ( HttpSessionEvent se );
    
    public void sessionDestroyed ( HttpSessionEvent se )
    }

自定义监听器实现HttpSessionListener,统计网站在线人数

public class MyHttpSessionListener implements HttpSessionListener{
	public static int peopleOnLine = 0;
	@Override
	public void sessionCreated(HttpSessionEvent arg0) {
		System.out.println("myHttpSessionListener.sessionCreated():"+arg0);
		peopleOnLine++;
		arg0.getSession().setAttribute("peopleOnLine",peopleOnLine);
	}
	@Override
	public void sessionDestroyed(HttpSessionEvent arg0) {
		System.out.println("myHttpSessionListener.sessionDestroyed():"+arg0);
		peopleOnLine--;
		arg0.getSession().setAttribute("peopleOnLine",peopleOnLine);
	}
}

web.xml中的配置

<listener> 
    <listener-class>com.sansux.listener.MyHttpSessionListener</listener-class>
</listener>

在前端页面获取在线人数

<%=session.getAttribute("peopleOnLine")%>

猜你喜欢

转载自blog.csdn.net/zhouhaihua57410/article/details/82824222
今日推荐