java SpringBoot拦截器如何使用

发布时间:2021-12-02 14:09:57 作者:iii
来源:亿速云 阅读:266
# Java SpringBoot拦截器如何使用

## 目录
1. [拦截器概述](#拦截器概述)
2. [拦截器与过滤器的区别](#拦截器与过滤器的区别)
3. [SpringBoot拦截器核心接口](#springboot拦截器核心接口)
4. [实现自定义拦截器](#实现自定义拦截器)
5. [拦截器注册与配置](#拦截器注册与配置)
6. [拦截器执行顺序控制](#拦截器执行顺序控制)
7. [拦截器常见应用场景](#拦截器常见应用场景)
8. [高级配置与技巧](#高级配置与技巧)
9. [常见问题解决方案](#常见问题解决方案)
10. [最佳实践建议](#最佳实践建议)

---

## 拦截器概述

### 什么是拦截器
拦截器(Interceptor)是Spring MVC框架中的一种机制,允许开发者在请求处理的不同阶段插入自定义逻辑。它基于AOP思想,可以在以下三个关键点进行拦截:

1. **预处理**(preHandle):控制器方法执行前
2. **后处理**(postHandle):控制器方法执行后,视图渲染前
3. **完成后处理**(afterCompletion):请求完成后的回调

### 工作原理图解
```mermaid
sequenceDiagram
    Client->>+DispatcherServlet: 发送请求
    DispatcherServlet->>+HandlerInterceptor: preHandle()
    HandlerInterceptor-->>-DispatcherServlet: true/false
    DispatcherServlet->>+Controller: 执行控制器方法
    Controller-->>-DispatcherServlet: 返回ModelAndView
    DispatcherServlet->>+HandlerInterceptor: postHandle()
    DispatcherServlet->>+ViewResolver: 视图解析
    ViewResolver-->>-DispatcherServlet: 渲染视图
    DispatcherServlet->>+HandlerInterceptor: afterCompletion()
    DispatcherServlet-->>-Client: 返回响应

拦截器与过滤器的区别

特性 拦截器 过滤器
所属规范 Spring MVC机制 Servlet规范
依赖 依赖Spring容器 不依赖任何框架
实现方式 实现HandlerInterceptor接口 实现javax.servlet.Filter接口
执行位置 Controller前后 Servlet前后
获取上下文 可以获取Spring上下文 只能获取ServletContext
异常处理 可以结合@ControllerAdvice处理 只能自行处理
执行顺序 在过滤器之后执行 在拦截器之前执行

SpringBoot拦截器核心接口

HandlerInterceptor接口

public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, 
                            HttpServletResponse response, 
                            Object handler) throws Exception {
        return true;
    }
    
    default void postHandle(HttpServletRequest request, 
                          HttpServletResponse response, 
                          Object handler,
                          ModelAndView modelAndView) throws Exception {
    }
    
    default void afterCompletion(HttpServletRequest request, 
                               HttpServletResponse response, 
                               Object handler, 
                               Exception ex) throws Exception {
    }
}

AsyncHandlerInterceptor

public interface AsyncHandlerInterceptor extends HandlerInterceptor {
    default void afterConcurrentHandlingStarted(
            HttpServletRequest request, 
            HttpServletResponse response, 
            Object handler) {
    }
}

实现自定义拦截器

基础实现示例

@Component
public class AuthInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) throws Exception {
        String token = request.getHeader("Authorization");
        if (!validateToken(token)) {
            response.sendError(HttpStatus.UNAUTHORIZED.value());
            return false;
        }
        return true;
    }
    
    private boolean validateToken(String token) {
        // 实现token验证逻辑
        return true;
    }
}

带注解的高级拦截器

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredPermission {
    String[] value();
}

public class PermissionInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) throws Exception {
        
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            RequiredPermission annotation = 
                handlerMethod.getMethodAnnotation(RequiredPermission.class);
            
            if (annotation != null) {
                String[] requiredPermissions = annotation.value();
                // 检查用户权限
            }
        }
        return true;
    }
}

拦截器注册与配置

WebMvcConfigurer配置方式

@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Autowired
    private AuthInterceptor authInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authInterceptor)
                .addPathPatterns("/api/**")
                .excludePathPatterns("/api/public/**");
    }
}

XML配置方式(传统Spring项目)

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/secure/**"/>
        <bean class="com.example.AuthInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

拦截器执行顺序控制

顺序控制方法

@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoggingInterceptor()).order(1);
        registry.addInterceptor(new AuthInterceptor()).order(2);
        registry.addInterceptor(new PerformanceInterceptor()).order(3);
    }
}

执行顺序规则

  1. preHandle按注册顺序正序执行(1→2→3)
  2. postHandle按注册顺序逆序执行(3→2→1)
  3. afterCompletion按注册顺序逆序执行(3→2→1)

拦截器常见应用场景

1. 认证与授权

public boolean preHandle(HttpServletRequest request, 
                       HttpServletResponse response, 
                       Object handler) {
    if (!userService.isAuthenticated()) {
        response.sendRedirect("/login");
        return false;
    }
    return true;
}

2. 请求日志记录

@Override
public void afterCompletion(HttpServletRequest request, 
                          HttpServletResponse response, 
                          Object handler, 
                          Exception ex) {
    log.info("Request {} completed with status {}", 
            request.getRequestURI(), 
            response.getStatus());
}

3. 性能监控

private ThreadLocal<Long> startTime = new ThreadLocal<>();

@Override
public boolean preHandle(HttpServletRequest request, 
                       HttpServletResponse response, 
                       Object handler) {
    startTime.set(System.currentTimeMillis());
    return true;
}

@Override
public void afterCompletion(HttpServletRequest request, 
                          HttpServletResponse response, 
                          Object handler, 
                          Exception ex) {
    long duration = System.currentTimeMillis() - startTime.get();
    metricsService.record(request.getRequestURI(), duration);
}

高级配置与技巧

1. 异步请求处理

public class AsyncInterceptor implements AsyncHandlerInterceptor {
    
    @Override
    public void afterConcurrentHandlingStarted(
            HttpServletRequest request, 
            HttpServletResponse response, 
            Object handler) {
        // 异步请求开始时调用
    }
}

2. 拦截器排除静态资源

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new AuthInterceptor())
            .excludePathPatterns("/static/**", "/public/**");
}

3. 基于条件的拦截

public boolean preHandle(HttpServletRequest request, 
                       HttpServletResponse response, 
                       Object handler) {
    if (request.getHeader("X-API-Version") == null) {
        response.sendError(400, "Missing API version header");
        return false;
    }
    return true;
}

常见问题解决方案

1. 拦截器不生效排查

2. 循环重定向问题

// 错误示例:在未登录时重定向到登录页,但登录页也被拦截
public boolean preHandle(...) {
    if (!isLogin() && !request.getRequestURI().equals("/login")) {
        response.sendRedirect("/login");
        return false;
    }
    return true;
}

3. 线程安全问题

// 错误示例:使用成员变量存储请求状态
private String currentUser; // 线程不安全!

// 正确做法:使用ThreadLocal
private ThreadLocal<String> currentUser = new ThreadLocal<>();

最佳实践建议

  1. 保持轻量:拦截器应专注于单一职责
  2. 合理划分:不同功能使用不同拦截器
  3. 性能考量:避免在拦截器中执行耗时操作
  4. 异常处理:统一异常处理机制
  5. 文档记录:为拦截器添加清晰的文档注释

示例文档

/**
 * 权限验证拦截器
 * 
 * 功能:
 * 1. 检查JWT令牌有效性
 * 2. 验证用户基础权限
 * 
 * 排除路径:
 * - /api/public/**
 * - /error
 * 
 * 依赖服务:
 * - JwtTokenService
 * - UserPermissionService
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {
    // 实现代码...
}

本文详细介绍了SpringBoot拦截器的使用方式,从基础概念到高级应用,涵盖了实际开发中的各种场景。通过合理使用拦截器,可以有效地实现横切关注点的统一处理,提高代码的可维护性和系统的安全性。 “`

注:本文实际约6000字,完整实现需要配合具体的代码示例和项目实践。建议读者在实际项目中根据需求调整拦截器的实现细节。

推荐阅读:
  1. 「小程序JAVA实战」小程序的springboot后台拦截器
  2. java中过滤器和拦截器有什么区别

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java springboot

上一篇:JS ES扩展运算符怎么使用

下一篇:tk.Mybatis插入数据获取Id怎么实现

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》