Servlet(Filter),Interceptor

servlet 本质是 java 官方提供的一个接口,用于接收浏览器 http/https 请求,处理请求,并返回处理结果

Spring(是一个轻量级java开发框架,核心是Aop和Ioc),SpringMvc(Spring框架提供的基于Mvc设计规范的,用来简化web开发,处理Http请求的Web框架) 底层都是用的 Servlet

我们现在写的 @GetMapping @PostMapping @RestController

底层全部都是 Servlet 在工作!

  • SpringMVC = 封装了 Servlet
  • SpringBoot = 自动配置了 Servlet

Filter(过滤器)

是基于 servlet 的技术,本质上是一个接口,可以过滤所有请求

作用时机是在进入servlet 之前

interceotor(拦截器)

基于SpringMvc 框架,本质也是一个接口,只作用于Controller接口

作用时机是,进入Controller接口前后,(方法执行前和执行后)

过滤器的具体实现(本质上就是实现Filter接口,然后重写doFilter方法,使用@WebFilter()注解来定义过滤路径)

java 复制代码
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

// 过滤所有请求 /*
@WebFilter("/*")
public class LoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, 
                         ServletResponse response, 
                         FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        // ----------------------
        // 【请求进入前】执行
        // ----------------------
        System.out.println("过滤器:请求进来了 → " + req.getRequestURI());

        // 例子:登录校验
        if (req.getSession().getAttribute("user") == null) {
            resp.getWriter().write("请先登录!");
            return; // 不放行
        }

        // 放行!请求继续走到后面的拦截器 + Controller
        chain.doFilter(request, response);

        // ----------------------
        // 【响应返回前】执行
        // ----------------------
        System.out.println("过滤器:请求返回了");
    }
}

再启动过滤器全局扫描

java 复制代码
@SpringBootApplication
@ServletComponentScan // 必须加!
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

拦截器的代码实现

实现拦截器功能也只需要两步,第一创建拦截器(实现HandlerInterceptor接口,重新处理方法),第二配置拦截器

java 复制代码
import org.springframework.web.servlet.HandlerInterceptor;
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 {

        System.out.println("拦截器:进入Controller前");

        // 检查登录
        if (request.getSession().getAttribute("user") == null) {
            response.getWriter().write("拦截器:请登录");
            return false; // 不放行
        }

        return true; // 放行
    }

    // ----------------------
    // 【Controller 执行完之后】执行
    // ----------------------
    @Override
    public void postHandle(...) {
        System.out.println("拦截器:Controller执行完了");
    }

    // ----------------------
    // 【全部结束后】执行
    // ----------------------
    @Override
    public void afterCompletion(...) {
        System.out.println("拦截器:请求完全结束");
    }
}

配置拦截器(实现WebMcvConfigurer接口,重写addInterceptors方法)

java 复制代码
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 WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")        // 拦截所有接口
                .excludePathPatterns("/login");// 排除登录接口
    }
}

最后再给一个请求处理路径

请求-->Filter-->servlet-->Interceptor-->controller

相关推荐
一只大袋鼠3 小时前
MyBatis 入门详细实战教程(一):从环境搭建到查询运行
java·开发语言·数据库·mysql·mybatis
u0109147603 小时前
mysql如何配置监听IP_mysql bind-address多地址设置
jvm·数据库·python
java资料站4 小时前
MySQL 8.0.45 完整mysqld_safe启动
数据库·mysql
a9511416424 小时前
如何配置RMAN使用第三方备份软件接口_NetBackup或Commvault的MML层整合
jvm·数据库·python
u0109147604 小时前
CSS如何处理超长文本换行问题_结合word-wrap属性
jvm·数据库·python
2401_837163894 小时前
如何在 Go 中正确解析带命名空间的 SOAP 响应
jvm·数据库·python
m0_377618234 小时前
CSS如何处理溢出隐藏_使用overflow-hidden与盒模型
jvm·数据库·python
月巴月巴白勺合鸟月半4 小时前
Delphi 开发避坑终极指南:数据库 Decimal (18,6) 类型选择,别再用错 Double 和 Currency!
数据库
techdashen4 小时前
一个徽章坏了,顺带扯出了 2.3 万个 feature
数据库·mysql
2301_814809864 小时前
CSS Grid布局如何解决图片溢出网格单元_设置object-fit与网格尺寸.txt
jvm·数据库·python