溫馨提示×

溫馨提示×

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

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

SpringMVC?HandlerInterceptor攔截器的使用與參數是什么

發布時間:2022-01-19 09:11:02 來源:億速云 閱讀:227 作者:柒染 欄目:開發技術
# SpringMVC HandlerInterceptor攔截器的使用與參數詳解

## 一、攔截器概述

### 1.1 什么是HandlerInterceptor
HandlerInterceptor是Spring MVC框架中提供的一種攔截機制,允許開發者在請求處理的不同階段插入自定義邏輯。它類似于Servlet規范中的Filter,但提供了更細粒度的控制能力。

```java
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 {
    }
}

1.2 攔截器與過濾器的區別

特性 HandlerInterceptor Filter
所屬規范 Spring MVC特有 Servlet規范
執行位置 DispatcherServlet之后 Servlet容器級別
依賴關系 需要Spring容器支持 不依賴Spring
獲取上下文 可以獲取Spring上下文 無法直接獲取
控制粒度 方法級別攔截 URL級別攔截

二、核心方法詳解

2.1 preHandle方法

在處理器方法執行前被調用,是最常用的攔截點。

參數說明: - HttpServletRequest request:HTTP請求對象 - HttpServletResponse response:HTTP響應對象 - Object handler:被攔截的控制器方法(HandlerMethod實例)

返回值: - true:繼續執行后續攔截器和處理器 - false:中斷執行流程

典型應用場景:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // 登錄檢查
    if (request.getSession().getAttribute("user") == null) {
        response.sendRedirect("/login");
        return false;
    }
    return true;
}

2.2 postHandle方法

在處理器方法執行后,視圖渲染前被調用。

新增參數: - ModelAndView modelAndView:控制器返回的模型和視圖對象

注意事項: - 僅當preHandle返回true時才會執行 - 異常發生時不會執行

使用示例:

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, 
                      Object handler, ModelAndView modelAndView) {
    // 向所有視圖添加公共參數
    if (modelAndView != null) {
        modelAndView.addObject("version", "1.0.0");
    }
}

2.3 afterCompletion方法

在整個請求完成(視圖渲染完畢)后執行。

新增參數: - Exception ex:處理器拋出的異常(如果有)

典型用途:

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
                          Object handler, Exception ex) {
    // 資源清理
    DatabaseConnectionPool.releaseAll();
    
    // 異常日志記錄
    if (ex != null) {
        log.error("Request processing failed", ex);
    }
}

三、高級配置技巧

3.1 攔截器注冊方式

通過WebMvcConfigurer實現配置:

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

3.2 路徑匹配模式

支持Ant風格路徑匹配: - ? 匹配單個字符 - * 匹配0或多個字符 - ** 匹配0或多個目錄

示例:

.addPathPatterns("/user/*/profile")  // 匹配/user/123/profile
.addPathPatterns("/admin/**")       // 匹配所有/admin/下的路徑

3.3 攔截器執行順序

通過order方法控制順序(數值越小優先級越高):

registry.addInterceptor(new LogInterceptor()).order(1);
registry.addInterceptor(new AuthInterceptor()).order(2);

四、實戰應用案例

4.1 性能監控攔截器

public class PerformanceInterceptor implements HandlerInterceptor {
    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();
        log.info("{}耗時: {}ms", request.getRequestURI(), duration);
        startTime.remove();
    }
}

4.2 接口冪等性檢查

public class IdempotentInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String token = request.getHeader("Idempotent-Token");
        if (StringUtils.isEmpty(token)) {
            throw new BusinessException(400, "冪等Token缺失");
        }
        
        Boolean result = redisTemplate.opsForValue().setIfAbsent("idempotent:" + token, "1", 24, TimeUnit.HOURS);
        if (Boolean.FALSE.equals(result)) {
            throw new BusinessException(400, "請勿重復提交");
        }
        return true;
    }
}

五、常見問題排查

5.1 攔截器不生效的可能原因

  1. 配置未加載:檢查@Configuration類是否被掃描
  2. 路徑不匹配:確認addPathPatterns配置正確
  3. 順序問題:其他攔截器中斷了執行鏈
  4. Spring版本差異:注意Spring Boot 2.x與3.x的配置差異

5.2 獲取控制器方法信息

if (handler instanceof HandlerMethod) {
    HandlerMethod handlerMethod = (HandlerMethod) handler;
    Method method = handlerMethod.getMethod();
    // 獲取方法上的注解
    RequestMapping annotation = method.getAnnotation(RequestMapping.class);
}

六、擴展進階

6.1 異步請求處理

對于異步請求(Callable/DeferredResult),需要實現AsyncHandlerInterceptor:

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

6.2 與Spring Security集成

當同時使用Spring Security時,注意執行順序: 1. Security FilterChain 2. HandlerInterceptor 3. @PreAuthorize等注解檢查

建議在SecurityConfig中配置:

http.addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class);

結語

HandlerInterceptor作為Spring MVC的核心擴展點,提供了靈活的請求處理干預能力。合理使用攔截器可以實現以下目標: - 統一橫切關注點(日志、鑒權等) - 減少重復代碼 - 增強系統可維護性 - 實現業務解耦

在實際項目中,建議將攔截器與AOP結合使用,根據場景選擇合適的技術方案。對于簡單的URL攔截優先使用攔截器,對于復雜的業務邏輯攔截可考慮AOP實現。 “`

注:本文實際約3500字,完整版可根據需要補充以下內容: 1. 更多實際代碼示例 2. 性能優化建議 3. 與Swagger等工具的集成方案 4. 多攔截器鏈式調用的調試技巧 5. 在響應式編程中的使用差異

向AI問一下細節

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

AI

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