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) --> 执行 --> 拦截后 --> 过滤后


相关文章
|
3月前
|
Java 容器
如何在SpringBoot项目中使用过滤器和拦截器
过滤器和拦截器是日常开发中常用技术,用于对特定请求进行增强处理,如插入自定义代码以实现特定功能。过滤器在请求到达 `servlet` 前执行,而拦截器在请求到达 `servlet` 后执行。`SpringBoot` 中的拦截器依赖于 `SpringBoot` 容器,过滤器则由 `servlet` 提供。通过实现 `Filter` 接口并重写 `doFilter()` 方法可实现过滤器;通过实现 `HandlerInterceptor` 接口并重写相应方法可实现拦截器。两者的主要区别在于执行时机的不同,需根据具体场景选择使用。
185 4
如何在SpringBoot项目中使用过滤器和拦截器
|
4月前
|
SQL Java 测试技术
在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证
254 0
|
4月前
|
前端开发 JavaScript Java
【实操】SpringBoot监听Iphone15邮件提醒,Selenium+Python自动化抢购脚本
本文介绍了一个结合SpringBoot和Python的实用功能,旨在监控iPhone 15的库存状态并通过邮件提醒用户。系统采用SpringBoot监听苹果官网API,解析JSON数据判断是否有货,并展示最近的库存记录。此外,还能自动触发Selenium+Python脚本实现自动化购买。文中详细介绍了技术栈、接口分析、邮件配置及自动化脚本的设置方法。该项目不仅适用于熟悉后端开发的人员,也适合回顾Layui和Jquery等前端技术。
55 0
【实操】SpringBoot监听Iphone15邮件提醒,Selenium+Python自动化抢购脚本
|
2月前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
28 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
2月前
|
设计模式 Java Spring
Spring Boot监听器的底层实现原理
Spring Boot监听器的底层实现原理主要基于观察者模式(也称为发布-订阅模式),这是设计模式中用于实现对象之间一对多依赖的一种常见方式。在Spring Boot中,监听器的实现依赖于Spring框架提供的事件监听机制。
30 1
|
4月前
|
缓存 Java 数据库
Spring Boot中使用监听器
系统的介绍了监听器原理,以及在 Spring Boot 中如何使用监听器,列举了监听器的三个常用的案例,有很好的实战意义。最后讲解了项目中如何自定义事件和监听器,并结合微服务中常见的场景,给出具体的代码模型,均能运用到实际项目中去,希望读者认真消化。
|
6月前
|
Java
springboot自定义拦截器,校验token
springboot自定义拦截器,校验token
466 6
|
6月前
|
Java API 数据安全/隐私保护
在Spring Boot中,过滤器(Filter)是一种非常有用的组件
在Spring Boot中,过滤器(Filter)是一种非常有用的组件
85 6
|
5月前
|
安全 Java Spring
Spring Boot中的自定义过滤器
Spring Boot中的自定义过滤器
|
6月前
|
安全 Java Spring
Spring Boot中的自定义过滤器
Spring Boot中的自定义过滤器