Java工具篇之浅析过滤器、拦截器和监听器

Java工具篇之浅析过滤器、拦截器和监听器

一、过滤器

1、概念

​ 过滤器即filter,基于servlet容器实现的系统级功能,能针对用户的访问请求进行管理,可以对web服务器管理所有的web资源,例如实现url级别的权限访问控制,过滤敏感词汇等。

2、流程

3、实现

首先要实现Filter接口,

在这里插入图片描述

也即实现init(), doFilter()以及destroy()三个方法,具体代码如下:

package com.example.util;


import org.apache.juli.logging.LogFactory;
import org.slf4j.Logger;

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

@WebFilter(urlPatterns = "/*", filterName = "checkFilter", initParams = {@WebInitParam(name = "charset", value = "utf-8")})
public class FilterUtil implements Filter {
    private Logger logger = (Logger) LogFactory.getLog(FilterUtil.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.info("=====================init filter=======================");
        logger.info(filterConfig.getFilterName());
        logger.info(filterConfig.getInitParameter("charset"));
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        logger.info("doFilter");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        logger.info("=====================destroy filter=======================");
    }
}

4、测试以及小结

项目启动的时候输出init,说明此时被初始化;

在访问的接口方法之前输出了doFilter,说明此处是在请求方法之前进行过滤的;

在这里插入图片描述

二、拦截器

1、概念

Interceptor,基于Java反射实现的非系统级别拦截,底层是基于JDK实现的动态代理,依赖于具体的接口,在运行期间动态生成字节码。

2、流程

在这里插入图片描述

3、 实现

首先实现自定义注解,代码如下:

package com.example.util;

import java.lang.annotation.*;


@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

}

然后编写自定义拦截器,代码如下:

package com.example.util;

import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;


@Aspect
@Component
public class MyInterceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger(MyInterceptor.class);

    /**
     * 预处理回调方法,实现处理器的预处理(如检查登陆),第三个参数为响应的处理器,自定义Controller
     * 返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时需要通过response来产生响应;
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            MyAnnotation myAnnotation =  handlerMethod.getMethodAnnotation(MyAnnotation.class);
            Method method = handlerMethod.getMethod();
            if (myAnnotation != null) {
                logger.info(method.getName() + "~~~");
                return true;
            }
        }
        logger.info("false~~~~~~~~~~");
        return false;
    }

    /**
     * 后处理回调方法,实现处理器的后处理(但在渲染视图之前)。
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        logger.info("===============post================");
    }

    /**
     * 整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        logger.info("=================after=====================");
    }
}

再将该拦截器添加到拦截器配置中,代码如下:

package com.example.config;

import com.example.util.MyInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
    }
}

4、测试以及小结

在测试接口上加上自定义的注解,然后访问测试,效果如下:

在这里插入图片描述

红框内是我们访问的接口方法名,成功输出,并且是在方法体之前输出的,与前面贴出的流程图吻合。

后面紧接着又进入拦截器一次,此处是其他原因引起的,因不影响测试,不再此赘述其原因。

三、监听器

1、概念

Java事件监听器是由事件类和监听接口组成,自定义一个事件前,必须提供一个事件的监听接口以及一个事件类。JAVA中监听接口是继承java.util.EventListener的类,事件类继承java.util.EventObject的类。

Java事件监听器属性的新增、删除和修改划分成三种,分别针对于ServletContext、HttpSession、ServletRequest对象

事件源:被监听的对象(三个域对象)

监听器:监听事件源对象,事件源对象的状态的变化都会触发

注册监听器:将监听器与事件源进行绑定

响应行为:监听器监听到事件源的状态变化时所涉及的功能代码

2、流程

在这里插入图片描述

3、实现

package com.example.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class MyServletContextListener implements ServletContextListener {
    private Logger logger = LoggerFactory.getLogger(MyServletContextListener.class);

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        logger.info("init listener.....");
    }
}

4、测试及小结

在这里插入图片描述

上图可以看到ServletContext对象的监听器在项目启动的时候被初始化,因为在项目启动的时候初始化servlet容器而被初始化(servlet容器初始化,ServletContextListener会获取ServletContext对象)。

四、总结

在这里插入图片描述

启动顺序:监听器 > 过滤器 > 拦截器

过滤器可以针对所有请求,拦截器是针对接口,监听器是针对某事件(例如servlet容器初始化事件)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值