SpringBoot2.0(过滤器,监听器,拦截器)

简介: SpringBoot2.0(过滤器,监听器,拦截器)

一,过滤器

1.1,自定义Filter

使用Servlet3.0的注解进行配置

启动类里面增加 @ServletComponentScan ,进行扫描

新建一个Filter类,implements Filter ,并实现对应接口

@WebFilter 标记一个类为Filter,被spring进行扫描

urlPatterns:拦截规则,支持正则

控制chain.doFilter的方法的调用,来实现是否通过放行,

不放行的话,web应用resp.sendRedirect(“/index.html”)

场景:权限控制,用户登录(非前端后端分离场景)等

1.2,启动类代码

package com.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan  // 扫描select的注解
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class,args);
    }
}

1.2,创建filter类和LoginFilter包


1.2.1,编写loginFilter类 过滤器代码

package com.demo.filter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
@WebFilter(urlPatterns = {"/*"})
@Order(Ordered.HIGHEST_PRECEDENCE)    // 设置过滤器的排序,int类型
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化过滤器");
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("doFilter");
//        servletResponse.setCharacterEncoding("UTF-8");
        // 设置响应的字符编码为UTF-8
        servletResponse.setCharacterEncoding("UTF-8");
        // 设置响应的内容类型为text/plain;charset=UTF-8
        servletResponse.setContentType("text/plain;charset=UTF-8");
        // 登录过滤器 有两种情况,需要放行
        // 1,登录请求要放行
        // 2. 不是登录请求,但是有登录token
        String uri = ((HttpServletRequest)servletRequest).getRequestURI();
        System.out.println(uri);
        if (uri.startsWith("/login/")){  // 判断是否以 /login/ 开头
            // 放行
            filterChain.doFilter(servletRequest,servletResponse);
        }else {
            // 从请求中获取token
            String token = ((HttpServletRequest)servletRequest).getParameter("token");
            if (token != null && !"".equals(token)){
                // 其实还需要进行解码,现在是只要有token就放行
                filterChain.doFilter(servletRequest,servletResponse);
            }else {
                PrintWriter pw = servletResponse.getWriter();
                pw.flush();
                pw.write("请先登录");
                pw.close();
            }
        }
    }
    @Override
    public void destroy() {
        System.out.println("销毁过滤器");
    }
}

1.2.2,创建二个Controller类

看看是不是以login开头的放行

第一个controller类为LoginController

package com.demo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/login")
public class LoginController {
    @RequestMapping("/doLogin")
    public Object doLogin(){
        return "登录接口";
    }
}

第二个controller类为HelloController

看看不是以login会不会过滤

package com.demo.controller;
import com.demo.bean.Person;
import com.demo.config.BootProperties;
import com.demo.config.SysProperties;
import com.demo.util.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.xml.crypto.Data;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.UUID;
@RestController
public class HelloController {
    @Autowired
    private BootProperties bootProperties;
    @RequestMapping("/test6")
    public Object test6(){
        return sysProperties.getParam1()+sysProperties.getParam2();
    }
}
// 整个之前的代码试试


证明过滤了,试试登录后

二,监听器

2.1,自定义监听器

  1. 自定义Listenter(常用监听器
    servletContextListenter,
    httpSessionListenter,
    HTTPSessionAttributeListenter,
    servletRequestListenter)

2.2,创建listenter包和MyListenter类

2.2.1,编写MyListenter类 监听器代码

package com.demo.listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class MyListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("请求被销毁");
    }
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("请求被初始化创建");
    }
}

三,拦截器

3.1,创建自定义拦截器配置类

@Configuration

继承WebMvcConfigurationAdapter(SpringBoot2.X之前旧版本)

SpringBoot2.X新版本配置拦截器 implements WebMvcConfigurer

3.2,创建配置包config和配置类MyWebMvcConfigurer

package com.demo.config;
import com.demo.interceptor.Logininterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration  // 添加了Configuration的类,我们称之为配置类
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new Logininterceptor()).addPathPatterns("/login/**");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

3.3,创建拦截器包interceptor和Logininterceptor类

Logininterceptor类代码

package com.demo.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Logininterceptor implements HandlerInterceptor {
    // 调用Controller某个方法之前,判断是否要不要处理
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return false; // false是拦截, 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");
    }
}

四,按顺序进行拦截,先注册,先被拦截

拦截器不生效的常见问题

  1. 是否有加@Configuration
  2. 拦截器是否有路径问题 ** 和 *
  3. 拦截器最后路径一定要 " /** " ,如果是目录的话则是 /*/

Filter

是基于函数回调 doFilter(),而lnterceptor则是基于AOP思想

Filter在只在Servlet前后起作用,而lnterceptor够深入到方法前后,异常抛出前后等


依赖于Servlet容器即web应用中,而lnterceptor不依赖于Servlet容器所以可以运行在多种环境。


在接口调用的声明周期里,lnterceptor可以被多次调用,而Filter只能在容器中初始化调用一次。


Filter和lnterceptor的执行顺序

过滤前 --> 拦截前 --> action(handler) --> 执行 --> 拦截后 --> 过滤后


相关文章
如何在SpringBoot项目中使用过滤器和拦截器
过滤器和拦截器是日常开发中常用技术,用于对特定请求进行增强处理,如插入自定义代码以实现特定功能。过滤器在请求到达 `servlet` 前执行,而拦截器在请求到达 `servlet` 后执行。`SpringBoot` 中的拦截器依赖于 `SpringBoot` 容器,过滤器则由 `servlet` 提供。通过实现 `Filter` 接口并重写 `doFilter()` 方法可实现过滤器;通过实现 `HandlerInterceptor` 接口并重写相应方法可实现拦截器。两者的主要区别在于执行时机的不同,需根据具体场景选择使用。
271 4
如何在SpringBoot项目中使用过滤器和拦截器
微服务——SpringBoot使用归纳——Spring Boot中使用监听器——Spring Boot中自定义事件监听
本文介绍了在Spring Boot中实现自定义事件监听的完整流程。首先通过继承`ApplicationEvent`创建自定义事件,例如包含用户数据的`MyEvent`。接着,实现`ApplicationListener`接口构建监听器,用于捕获并处理事件。最后,在服务层通过`ApplicationContext`发布事件,触发监听器执行相应逻辑。文章结合微服务场景,展示了如何在微服务A处理完逻辑后通知微服务B,具有很强的实战意义。
38 0
微服务——SpringBoot使用归纳——Spring Boot中使用监听器——监听器介绍和使用
本文介绍了在Spring Boot中使用监听器的方法。首先讲解了Web监听器的概念,即通过监听特定事件(如ServletContext、HttpSession和ServletRequest的创建与销毁)实现监控和处理逻辑。接着详细说明了三种实际应用场景:1) 监听Servlet上下文对象以初始化缓存数据;2) 监听HTTP会话Session对象统计在线用户数;3) 监听客户端请求的Servlet Request对象获取访问信息。每种场景均配有代码示例,帮助开发者理解并应用监听器功能。
35 0
java springboot监听事件和处理事件
通过上述步骤,开发者可以在Spring Boot项目中轻松实现事件的发布和监听。事件机制不仅解耦了业务逻辑,还提高了系统的可维护性和扩展性。掌握这一技术,可以显著提升开发效率和代码质量。
105 33
java springboot监听事件和处理事件
通过上述步骤,开发者可以在Spring Boot项目中轻松实现事件的发布和监听。事件机制不仅解耦了业务逻辑,还提高了系统的可维护性和扩展性。掌握这一技术,可以显著提升开发效率和代码质量。
108 13
|
3月前
|
Java Spring Boot监听事件和处理事件
通过上述步骤,我们可以在Java Spring Boot应用中实现事件的发布和监听。事件驱动模型可以帮助我们实现组件间的松耦合,提升系统的可维护性和可扩展性。无论是处理业务逻辑还是系统事件,Spring Boot的事件机制都提供了强大的支持和灵活性。希望本文能为您的开发工作提供实用的指导和帮助。
136 15
Java Springboot监听事件和处理事件
通过这些内容的详细介绍和实例解析,希望能帮助您深入理解Spring Boot中的事件机制,并在实际开发中灵活应用,提高系统的可维护性和扩展性。
81 7
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
88 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
Spring Boot监听器的底层实现原理
Spring Boot监听器的底层实现原理主要基于观察者模式(也称为发布-订阅模式),这是设计模式中用于实现对象之间一对多依赖的一种常见方式。在Spring Boot中,监听器的实现依赖于Spring框架提供的事件监听机制。
116 1
基于SpringBoot+Vue实现的留守儿童爱心网站设计与实现(计算机毕设项目实战+源码+文档)
博主是一位全网粉丝超过100万的CSDN特邀作者、博客专家,专注于Java、Python、PHP等技术领域。提供SpringBoot、Vue、HTML、Uniapp、PHP、Python、NodeJS、爬虫、数据可视化等技术服务,涵盖免费选题、功能设计、开题报告、论文辅导、答辩PPT等。系统采用SpringBoot后端框架和Vue前端框架,确保高效开发与良好用户体验。所有代码由博主亲自开发,并提供全程录音录屏讲解服务,保障学习效果。欢迎点赞、收藏、关注、评论,获取更多精品案例源码。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等