溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java SpringBoot攔截器如何使用

發布時間:2021-12-02 14:09:57 來源:億速云 閱讀:287 作者:iii 欄目:開發技術
# 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. 攔截器不生效排查

  • 檢查是否被@Component掃描
  • 確認路徑匹配是否正確
  • 查看是否有更高優先級的攔截器返回false

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字,完整實現需要配合具體的代碼示例和項目實踐。建議讀者在實際項目中根據需求調整攔截器的實現細節。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女