监听器,过滤器,拦截器

参考博文

作用

拦截器(interceptor):在一个请求进行中的时候,你想干预它的进展,甚至控制是否终止。这是拦截器做的事。
过滤器(Filter):当有一堆东西,只希望选择符合的东西。定义这些要求的工具,就是过滤器。
监听器(Listener):一个事件发生后,只希望获取这些事个事件发生的细节,而不去干预这个事件的执行过程,这就用到监听器

三者区别

拦截器(interceptor):依赖于web框架,基于Java的反射机制,属于AOP的一种应用。一个拦截器实例在一个controller生命周期内可以多次调用。只能拦截Controller的请求。

是在面向切面编程的就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

过滤器(Filter):依赖于Servlet容器,基于函数回掉,可以对几乎所有请求过滤,一个过滤器实例只能在容器初使化调用一次。

是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符.

监听器(Listener):web监听器是Servlet中的特殊的类,用于监听web的特定事件,随web应用启动而启动,只初始化一次。

Java的监听器,也是系统级别的监听。监听器随web应用的启动而启动。Java的监听器在c/s模式里面经常用到,它
会对特定的事件产生产生一个处理。监听在很多模式下用到,比如说观察者模式,就是一个使用监听器来实现的,在比如统计网站的在线人数。

过滤器监听器拦截器
关注的点web请求系统级别参数、对象部分web请求
如何实现函数回调事件java反射机制
应用场景设置字符编码,url级别权限访问,过滤敏感词汇,压缩响应信息统计网站在线人数,清除过期的
是否依赖servlet容器依赖不依赖
servlet提供的支持filterServletContextListener,HttpSessionListener
spring提供支持HandlerInterceptorAdapter,HandlerInterceptor
级别系统系统非系统

启动顺序

监听器,过滤器,拦截器

拦截器

简要说明

SpringBoot通过实现HandlerInterceptor接口实现拦截器,通过实现WebMvcConfigurer接口实现一个配置类,在配置类中注入拦截器,最后再通过@Configuration注解注入配置。

实现接口HandlerInterceptor

重写三个方法
preHandle 在请求处理之前进行调用(Controller方法调用之前)
postHandle 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
afterCompletion 整个请求结束之后被调用,也就是在DispatchServlet渲染了对应的视图之后执行(主要用于进行资源清理工作)

自定义拦截器

package com.geekmice.springbootselfexercise.interceptor;

import com.geekmice.springbootselfexercise.domain.UserDomain;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Objects;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.interceptor
 * @Author: pingmingbo
 * @CreateTime: 2023-09-12  13:35
 * @Description: 登录拦截器
 * @Version: 1.0
 */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("登录拦截器前置处理");
        HttpSession session = request.getSession();
        UserDomain user = (UserDomain) session.getAttribute("user");
        if (Objects.nonNull(user)) {
            log.info("当前用户已登录,继续后面流程");
            return true;
        }else{
            log.info("未登录,请登录");
            response.sendRedirect(request.getContextPath() + "/user/login");
            throw new IllegalArgumentException("未登录,请登录");
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("request : [{}]", request);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("request : [{}]", request);
    }
}

配置拦截器

package com.geekmice.springbootselfexercise.config;

import com.geekmice.springbootselfexercise.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.config
 * @Author: pingmingbo
 * @CreateTime: 2023-09-12  13:47
 * @Description: 配置拦截器
 * @Version: 1.0
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getLoginInterceptor())
                .addPathPatterns("/**");
    }

    @Bean
    public LoginInterceptor getLoginInterceptor(){
        return new LoginInterceptor();
    }
}

在这里插入图片描述

过滤器

简要说明

使用过滤器很简单,只需要实现Filter类,然后重写它的3个方法即可。

init方法:程序启动调用Filter的init()方法(永远只调用一次);在容器中创建当前过滤器的时候自动调用这个方法。
destory方法:程序停止调用Filter的destroy()方法(永远只调用一次);在容器中销毁当前过滤器的时候自动调用这个方法。
doFilter方法:doFilter()方法每次的访问请求如果符合拦截条件都会调用(程序第一次运行,会在servlet调用init()方法以后调用;不管第几次,都在调用doGet(),doPost()方法之前)。这个方法有3个参数,分别是ServletRequest、ServletResponse和FilterChain可以从参数中获取HttpServletReguest和HttpServletResponse对象进行相应的处理操作。

在springboot 启动类添加该注解@ServletComponentScan

package com.geekmice.springbootselfexercise;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan
@MapperScan("com.geekmice.springbootselfexercise.dao")
public class SpringBootSelfExerciseApplication {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(SpringBootSelfExerciseApplication.class);
        springApplication.run(args);
    }

}

写个过滤器类,实现Filter接口

package com.geekmice.springbootselfexercise.filter;

import com.geekmice.springbootselfexercise.param.MyRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.filter
 * @Author: pingmingbo
 * @CreateTime: 2023-09-05  09:27
 * @Description: 修改分页参数默认值
 * @Version: 1.0
 */
@Configuration
@Slf4j
@WebFilter(filterName = "authFilter", urlPatterns = {"/tzArea"})
public class InitValueFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("过滤器开始初始化 : [{}]" , filterConfig);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String pageSize = httpServletRequest.getParameter("pageSize");
        String pageNum = httpServletRequest.getParameter("pageNum");
        if(StringUtils.isAnyBlank(pageSize,pageNum)){
            pageSize="11";
            pageNum="1";
            Map<String,Object> map = new HashMap(16);
            map.put("pageSize", pageSize);
            map.put("pageNum", pageNum);
            MyRequestWrapper myRequestWrapper = new MyRequestWrapper(httpServletRequest, map);
            chain.doFilter(myRequestWrapper, response);
        }


    }

    @Override
    public void destroy() {
        log.info("过滤器销毁");
    }
}

监听器

简要说明

web监听器是一种 Servlet 中特殊的类,它们能帮助开发者监听 web 中特定的事件,比如 ServletContext, HttpSession, ServletRequest的创建和销毁;变量的创建、销毁和修改等。可以在某些动作前后增加处理,实现监控。

如何使用

自定义事件
package com.geekmice.springbootselfexercise.event;

import com.geekmice.springbootselfexercise.domain.UserDomain;
import org.springframework.context.ApplicationEvent;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.event
 * @Author: pingmingbo
 * @CreateTime: 2023-09-12  15:17
 * @Description: 自定义事件
 * @Version: 1.0
 */
public class MyEvent extends ApplicationEvent {

    private UserDomain userDomain;

    public MyEvent(Object source, UserDomain userDomain) {
        super(source);
        this.userDomain = userDomain;
    }

    public UserDomain getUserDomain() {
        return userDomain;
    }

    public void setUserDomain(UserDomain userDomain) {
        this.userDomain = userDomain;
    }
}
自定义过滤器
package com.geekmice.springbootselfexercise.listener;

import com.geekmice.springbootselfexercise.domain.UserDomain;
import com.geekmice.springbootselfexercise.event.MyEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.listener
 * @Author: pingmingbo
 * @CreateTime: 2023-09-12  15:20
 * @Description: 自定义监听器,监听事件
 * @Version: 1.0
 */
@Slf4j
@Component
public class MyListener implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent event) {
        // 获取事件中信息
        UserDomain userDomain = event.getUserDomain();
        // 用于逻辑处理
        log.info("userDomain : [{}]", userDomain);
    }
}
接口调用
package com.geekmice.springbootselfexercise.service.impl;

import com.geekmice.springbootselfexercise.domain.UserDomain;
import com.geekmice.springbootselfexercise.event.MyEvent;
import com.geekmice.springbootselfexercise.service.EventService;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @BelongsProject: spring-boot-self-exercise
 * @BelongsPackage: com.geekmice.springbootselfexercise.service.impl
 * @Author: pingmingbo
 * @CreateTime: 2023-09-12  15:25
 * @Description: 测试发布事件
 * @Version: 1.0
 */
@Service
public class EventServiceImpl implements EventService {
    @Resource
    private ApplicationContext applicationContext;

    @Override
    public void publishEvent() {
        UserDomain user = UserDomain.builder().userName("pmb").build();
        // 发布事件
        MyEvent myEvent = new MyEvent(this, user);
        applicationContext.publishEvent(myEvent);
        return;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值