java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java拦截器使用

Java中拦截器的使用实现步骤

作者:墨香染城城

在Java开发中,我们经常会遇到需要拦截所有接口的需求,比如在接口调用前后添加统一的日志、权限校验等功能,这篇文章主要给大家介绍了Java中拦截器使用的相关资料,需要的朋友可以参考下

一、拦截器的作用与执行时机

  1. 三个核心方法
    • preHandle(): 在Controller方法执行前调用(用于权限验证等)
    • postHandle(): 在Controller方法执行后、视图渲染前调用(可修改ModelAndView)
    • afterCompletion(): 在请求完全结束后调用(资源清理、日志记录)
  2. 执行流程

二、实现步骤

步骤1:创建自定义拦截器

实现继承  HandlerInterceptor 接口:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class AuthInterceptor implements HandlerInterceptor {

    // Controller执行前调用
    @Override
    public boolean preHandle(HttpServletRequest request, 
                             HttpServletResponse response, 
                             Object handler) throws Exception {
        System.out.println("--- preHandle executed ---");
        
        // 示例:验证登录
        if (request.getSession().getAttribute("user") == null) {
            response.sendRedirect("/login"); // 重定向到登录页
            return false; // 中断请求
        }
        return true; // 放行请求
    }

    // Controller执行后、视图渲染前调用
    @Override
    public void postHandle(HttpServletRequest request, 
                          HttpServletResponse response, 
                          Object handler, 
                          ModelAndView modelAndView) throws Exception {
        System.out.println("--- postHandle executed ---");
        // 可修改ModelAndView数据
        if (modelAndView != null) {
            modelAndView.addObject("timestamp", System.currentTimeMillis());
        }
    }

    // 请求完全结束后调用(视图渲染完毕)
    @Override
    public void afterCompletion(HttpServletRequest request, 
                               HttpServletResponse response, 
                               Object handler, 
                               Exception ex) throws Exception {
        System.out.println("--- afterCompletion executed ---");
        // 资源清理或记录请求耗时
    }
}

步骤2:注册拦截器到Spring MVC

创建配置类实现 继承  WebMvcConfigurer 接口

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 AuthInterceptor())
                .addPathPatterns("/**")             // 拦截所有路径
                .excludePathPatterns("/login", "/css/**"); // 排除路径
    }
}

步骤3:测试Controller

@RestController
public class TestController {
    
    @GetMapping("/home")
    public String home() {
        return "Welcome to home page!";
    }

    @GetMapping("/login")
    public String login() {
        return "Login page";
    }
}

三、关键配置详解

  1. 路径匹配规则
    • addPathPatterns("/admin/**"):拦截以 /admin/ 开头的所有路径
    • excludePathPatterns("/public/**"):排除静态资源
  2. 多拦截器顺序
registry.addInterceptor(new LogInterceptor()).order(1); // 数字越小优先级越高
registry.addInterceptor(new AuthInterceptor()).order(2);

执行顺序:
LogInterceptor.preHandle → AuthInterceptor.preHandle → Controller →
AuthInterceptor.postHandle → LogInterceptor.postHandle →
视图渲染 → AuthInterceptor.afterCompletion → LogInterceptor.afterCompletion

四、常见使用场景

  1. 身份认证:在 preHandle() 中校验Session/Token
  2. 日志记录:在 afterCompletion() 记录请求耗时
  3. 参数预处理:在 preHandle() 中统一处理请求参数
  4. 全局数据注入:在 postHandle() 中向Model添加公共数据

五、拦截器 vs 过滤器(Filter)

特性

拦截器 (Interceptor)

过滤器 (Filter)

归属

Spring MVC 机制

Servlet 规范

作用范围

仅针对Controller请求

所有请求(包括静态资源)

依赖

可访问Spring容器中的Bean

无法直接使用Spring Bean

执行时机

Controller方法前后

Servlet处理前后

实例化

受Spring管理(支持依赖注入)

由Web服务器管理

提示:优先使用拦截器处理Controller相关逻辑,过滤器更适合处理底层Servlet请求(如编码转换)。

六、最佳实践

  1. 避免阻塞操作:拦截器中不要执行耗时任务(影响吞吐量)
  2. 谨慎使用postHandle:如果Controller有 @ResponseBody,postHandle 不会生效(无视图渲染)
  3. 注入Bean的正确方式:
@Component
public class AuthInterceptor implements HandlerInterceptor {
    @Autowired // 拦截器本身需由Spring管理
    private UserService userService; 
}

// 注册时从容器获取
registry.addInterceptor(authInterceptor); 

通过以上步骤,您可以在Spring Boot中高效实现拦截逻辑。根据实际需求组合多个拦截器,构建灵活的处理链。

七、HandlerInterceptor 和 WebMvcConfigurer

在 Spring Boot 项目中,当创建拦截器时,我们需要处理两个独立的接口:HandlerInterceptor 和 WebMvcConfigurer

1. HandlerInterceptor 接口需要重写的方法

当创建自定义拦截器时,需要实现 HandlerInterceptor 接口并重写它的三个核心方法:

方法

说明

是否必须重写

preHandle()

在 Controller 方法执行前调用
(用于权限验证、参数预处理等)

✅ 通常必须

postHandle()

在 Controller 方法执行后、视图渲染前调用
(可修改 ModelAndView)

⚠️ 可选

afterCompletion()

在请求完全结束后调用
(用于资源清理、日志记录)

⚠️ 可选

public class AuthInterceptor implements HandlerInterceptor {
    
    // 必须重写(最常用)
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) {
        // 认证逻辑
        return true; // 返回 true 放行请求
    }
    
    // 可选重写
    @Override
    public void postHandle(HttpServletRequest request,
                          HttpServletResponse response,
                          Object handler,
                          ModelAndView modelAndView) {
        // 后处理逻辑
    }
    
    // 可选重写
    @Override
    public void afterCompletion(HttpServletRequest request,
                              HttpServletResponse response,
                              Object handler,
                              Exception ex) {
        // 清理资源
    }
}

2. WebMvcConfigurer接口需要重写的方法

当注册拦截器时,需要实现 WebMvcConfigurer 接口,但只需重写一个方法:

方法

说明

是否必须重写

addInterceptors()

注册自定义拦截器并配置拦截规则

✅ 必须

其他方法(与拦截器无关,可选重写):

示例实现:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    // 必须重写(唯一需要重写的方法)
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/**")          // 拦截所有路径
                .excludePathPatterns("/login");  // 排除登录页
    }
    
    // 其他方法不需要重写(除非有特殊需求)
    // 例如跨域配置(可选)
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*");
    }
}

3. 完整流程图示

4. 关键注意事项

  1. HandlerInterceptor 方法重写规则
    • preHandle() 必须返回 booleantrue=放行,false=中断)
    • postHandle() 仅在返回视图时生效(对 @ResponseBody 无效)
    • afterCompletion() 总是执行(即使 Controller 抛出异常)
  2. WebMvcConfigurer 最佳实践
@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Autowired // 推荐注入拦截器(不要new实例)
    private AuthInterceptor authInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 设置多拦截器顺序
        registry.addInterceptor(new LogInterceptor()).order(0);
        registry.addInterceptor(authInterceptor).order(1)
             .addPathPatterns("/secure/**");
    }
}

常见错误 :

5. 两种接口的关系总结

特性

HandlerInterceptor

WebMvcConfigurer

角色

定义拦截逻辑

注册拦截器

重写方法

preHandle()
postHandle()
afterCompletion()

addInterceptors()

使用场景

业务逻辑实现

配置管理

实例数量

每个拦截器一个实现类

整个项目只需一个配置类

注解要求

@Component(可选)

@Configuration(必须)

💡 简单记忆:

总结 

到此这篇关于Java中拦截器的使用实现的文章就介绍到这了,更多相关Java拦截器使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文