在使用 SpringMVC + Spring + MyBatis (SSM) 搭建項目時,很多開發者都會遇到一個「看似詭異實則經典」的問題:Controller 請求正常、數據返回無誤,但頁面樣式全亂、JS 失效,瀏覽器 Network 面板顯示 CSS/JS 文件 404 或未請求到。路徑檢查無數遍沒錯,編碼也是 UTF-8,這時候往往是 DispatcherServlet 的攔截配置「過於激進」把靜態資源請求也攔截了。
SpringMVC 的前端控制器 DispatcherServlet 默認配置 `
利用 Servlet 容器(如 Tomcat)自帶的 default Servlet 專門處理靜態資源請求,繞過 SpringMVC。
<!-- web.xml 中配置 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/css/*</url-pattern>
<url-pattern>/js/*</url-pattern>
<url-pattern>/images/*</url-pattern>
<url-pattern>/fonts/*</url-pattern>
</servlet-mapping>
注意: 若你的 Web 容器默認 Servlet 名稱不是 "default"(如 Jetty 可能不同),需在 SpringMVC 配置文件中顯式指定:
<mvc:default-servlet-handler default-servlet-name="你的容器默認Servlet名" />
將攔截路徑從 `/` 改為 `*.action`、`.do` 或 `*.html` 等具體後綴,靜態資源請求自然不會進入 SpringMVC。
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern> <!-- 僅攔截 .action 結尾的請求 -->
</servlet-mapping>
此時訪問地址需帶後綴:`https://localhost:8080/project/login.action`。缺點:RESTful 風格 URL 不再純粹,前後端分離項目不推薦。
在 SpringMVC 配置文件中聲明靜態資源映射,讓框架知道哪些路徑對應靜態文件目錄。
<!-- springmvc-servlet.xml --> <mvc:resources mapping="/css/**" location="/static/css/" /> <mvc:resources mapping="/js/**" location="/static/js/" /> <mvc:resources mapping="/images/**" location="/static/images/" /> <mvc:annotation-driven /> <!-- 必須開啟註解驅動,否則 resources 可能不生效 -->
常見坑點:
靜態資源被攔截本質是 URL 映射衝突。理解 `DispatcherServlet`、`default Servlet`、靜態資源目錄三者關係,對症下藥即可輕松解決。記住:好的提問能事半功倍,直擊本質才能高效解決問題。