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

Spring MVC 導致自定義攔截器失效的根因與解決方案

     編輯:Java 綜合教學

Spring MVC <mvc:annotation-driven/> 導致自定義攔截器失效的根因與解決方案

<mvc:annotation-driven/> 會註冊兩個內部攔截器(ConversionServiceExposingInterceptor、ResourceUrlEncodingInterceptor),若配置不當會導致自定義攔截器不生效。本文記錄排查過程與完整解決方案。

問題現象

  • 配置了 <mvc:interceptors> 但自定義攔截器不執行
  • 靜態資源被攔截導致 404
  • 折騰兩天未果,最終請教師父解決

根因分析

  1. <mvc:annotation-driven/> 必須聲明,但會改變攔截器鏈順序
  2. 未正確配置靜態資源排除,導致攔截器處理靜態請求拋異常
  3. Spring 和 Spring MVC 重複掃描 @Controller,導致 Bean 創建兩次

完整解決方案:DispatcherServlet 配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
       xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="https://www.springframework.org/schema/context"
       xmlns:mvc="https://www.springframework.org/schema/mvc"
       xsi:schemaLocation="...">

    <!-- 1. 默認 Servlet 處理靜態資源 -->
    <mvc:default-servlet-handler/>

    <!-- 2. 註解驅動(必須) -->
    <mvc:annotation-driven/>

    <!-- 3. 掃描 Controller,排除 Service 等 -->
    <context:component-scan base-package="com.muke.controller" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 4. 視圖解析器 -->
    <bean id="viewResolverJsp" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!-- 5. 關鍵:攔截器配置,正確排除靜態資源 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <!-- 排除靜態資源目錄 -->
            <mvc:exclude-mapping path="/html/**"/>
            <mvc:exclude-mapping path="/back_css/**"/>
            <mvc:exclude-mapping path="/back_js/**"/>
            <mvc:exclude-mapping path="/back_img/**"/>
            <mvc:exclude-mapping path="/back_other/**"/>
            <mvc:exclude-mapping path="/layer/**"/>
            <mvc:exclude-mapping path="/laypage/**"/>
            <bean class="com.muke.springMVC.interceptors.DefaultInterceptors"/>
        </mvc:interceptor>
        
        <mvc:interceptor>
            <mvc:mapping path="/manage/menuBar/**"/>
            <bean class="com.muke.springMVC.interceptors.ManagerPowerInterceptors"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

根配置:避免重複掃描

<!-- applicationContext.xml -->
<context:component-scan base-package="com.muke" use-default-filters="false">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

原則:Spring 掃描 Service/DAO/Component,Spring MVC 只掃描 Controller,互斥配置避免重複代理。

總結經驗

  • 靜態資源必須排除:使用 mvc:exclude-mapping 按目錄/後綴排除
  • 掃描包要分離:根上下文與 Web 上下文職責劃分清晰
  • 默認 Servlet 處理器:<mvc:default-servlet-handler/> 讓容器原生處理靜態資源
  • 調試技巧:啟用 org.springframework.web DEBUG 日誌,觀察攔截器鏈執行順序

總結

攔截器失效多因配置順序、靜態資源衝突、重複掃描引起。遵循「分離掃描、排除靜態、啟用默認 Servlet」三原則,配合結構化日誌調試,可徹底解決此類問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved