首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring MVC 攔截器實現 Controller 接口訪問日誌記錄

     編輯:Java 綜合教學

Spring MVC 攔截器實現 Controller 接口訪問日誌記錄

在基於 Spring + Spring MVC + Hibernate 的 Java Web 項目中,為了便於開發調試與線上排查,記錄 HTTP 請求的處理詳情(訪問時間、Controller 路徑、方法名、請求參數、處理耗時等)至關重要。利用 Spring MVC 的 HandlerInterceptor 機制,可無侵入式地實現全鏈路訪問日誌記錄。

攔截器核心實現

package com.api.web.interceptor;

import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.yijia.api.util.SimpleDateFormatCache;

public class TimeCostInterceptor implements HandlerInterceptor {
    private static final Logger logger = Logger.getLogger(TimeCostInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        long startTime = System.currentTimeMillis();
        request.setAttribute("startTime", startTime);

        if (handler instanceof HandlerMethod) {
            HandlerMethod hm = (HandlerMethod) handler;
            StringBuilder sb = new StringBuilder(1000);
            sb.append("-----------------------")
              .append(SimpleDateFormatCache.getYmdhms().format(new Date()))
              .append("-------------------------------------\n");
            sb.append("Controller: ").append(hm.getBean().getClass().getName()).append("\n");
            sb.append("Method    : ").append(hm.getMethod().getName()).append("\n");
            sb.append("Params    : ").append(getParamString(request.getParameterMap())).append("\n");
            sb.append("URI       : ").append(request.getRequestURI()).append("\n");
            logger.info(sb.toString()); // 建議使用日誌框架而非 System.out
        }
        return true; // 繼續執行後續攔截器與 Controller
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        if (handler instanceof HandlerMethod) {
            long startTime = (Long) request.getAttribute("startTime");
            long executeTime = System.currentTimeMillis() - startTime;
            logger.info("CostTime : " + executeTime + "ms\n" + "-------------------------------------------------------------------------------");
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 可在此處理異常日誌、資源清理等
        if (ex != null) {
            logger.error("Request processing failed: " + request.getRequestURI(), ex);
        }
    }

    private String getParamString(Map<String, String[]> paramMap) {
        StringBuilder sb = new StringBuilder();
        for (Entry<String, String[]> entry : paramMap.entrySet()) {
            sb.append(entry.getKey()).append("=");
            String[] values = entry.getValue();
            if (values != null && values.length == 1) {
                sb.append(values[0]).append("\t");
            } else {
                sb.append(Arrays.toString(values)).append("\t");
            }
        }
        return sb.toString();
    }
}

Spring MVC 配置接入

在 spring-mvc.xml 中註冊攔截器,支持路徑匹配與排除:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/"/>
        <mvc:exclude-mapping path="/test"/>
        <bean class="com.api.web.interceptor.TimeCostInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

日誌輸出效果

攔截器日誌輸出示例

擴展應用場景

  • 用戶登錄/權限校驗:在 preHandle 中檢查 Session/Token,未通過直接返回 401 或重定向登錄頁。
  • 跨域 CORS 處理:統一設置 Access-Control-Allow-* 響應頭。
  • 請求限流/熔斷:結合 Guava RateLimiter 或 Resilience4j 實現接口級限流。
  • 鏈路追蹤:生成 TraceId 並傳遞給下游服務,配合 SkyWalking/Zipkin 實現分布式追蹤。

注意事項

  1. preHandle 返回 false 將中斷請求處理鏈,需自行寫入響應(如重定向、輸出 JSON 錯誤)。
  2. 避免在攔截器中進行耗時操作(如數據庫查詢、外部 HTTP 調用),影響吞吐量。
  3. 生產環境建議使用異步日誌框架(Log4j2 AsyncAppender、Logback AsyncAppender)防止日誌阻塞業務線程。
  4. 敏感參數(密碼、Token、身份證號)務必在 getParamString 中脫敏或過濾。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved