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

Spring MVC 靜態資源訪問三大方案總結:default-servlet、mvc:resources、mvc:default-servlet-handler

     編輯:Java 相關知識

當 DispatcherServlet 映射為 / 時,會攔截所有請求導致靜態資源(JS、CSS、圖片)返回 404。本文總結三種標準解決方案,並分析其原理、優缺點與執行順序。

問題根源


<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern> <!-- 攔截所有請求 -->
</servlet-mapping>

靜態資源請求進入 Spring MVC,找不到對應 @Controller,拋出 No mapping found。

方案一:啟用容器預設 Servlet(web.xml 配置)


<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>
  • 原理:讓容器的 DefaultServlet 先處理靜態資源,不進入 Spring。
  • 優點:效能最好,繞過 Spring 處理鏈。
  • 缺點:需逐一配置副檔名;不同容器預設 Servlet 名稱不同(Tomcat/Jetty/JBoss: default, WebLogic: FileServlet, WebSphere: SimpleFileServlet)。
  • 順序:必須寫在 DispatcherServlet 映射之前。

方案二:<mvc:resources>(Spring 3.0.4+ 推薦)


<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:resources mapping="/static/**" location="classpath:/static/" cache-period="31536000" />
  • 原理:註冊 ResourceHttpRequestHandler 到 SimpleUrlHandlerMapping,order=2147483646。
  • 支援:Web 根目錄、Classpath、Jar 內資源。
  • 快取:cache-period 設定 Cache-Control 標頭。
  • 需配合:<mvc:annotation-driven />,否則會報 No mapping found。
  • 注意:不要對 SimpleUrlHandlerMapping 設定 defaultHandler,否則靜態資源無法處理。

方案三:<mvc:default-servlet-handler/>(最簡單)


<mvc:default-servlet-handler />
  • 原理:註冊 DefaultServletHttpRequestHandler 到 SimpleUrlHandlerMapping,order=2147483647(最低優先級),匹配 /**。
  • 自動偵測:根據容器類型自動找預設 Servlet 名稱。
  • 優點:零配置、跨容器相容。
  • 缺點:所有未匹配請求都會走到此 Handler,效能略低於方案二。

HandlerMapping 執行順序與效能

HandlerMappingOrder匹配模式
DefaultAnnotationHandlerMapping0@RequestMapping
ResourceHttpRequestHandler (mvc:resources)2147483646/resources/**
DefaultServletHttpRequestHandler (default-servlet-handler)2147483647/**

請求流程:@Controller 先匹配 → 失敗 → mvc:resources → 失敗 → default-servlet-handler(容器 DefaultServlet)。

最佳實踐建議

  1. 生產環境:Nginx/Apache 直接服務靜態資源,不經 Java 應用,效能最佳。
  2. 開發/簡單部署:使用 <mvc:resources> 映射 /static/**、/assets/**,資源放 src/main/resources/static 或 src/main/webapp/static。
  3. 避免:將 DispatcherServlet 映射為 *.do、*.action 等後綴,雖能解決靜態資源問題,但不符合 REST 風格。

總結

三種方案各有適用場景:容器級方案效能最好但配置繁瑣;mvc:resources 功能最豐富支援 Classpath/Jar;mvc:default-servlet-handler 最省事。現代 Spring Boot 專案預設已配置 ResourceHttpRequestHandler,資源置於 static/public/resources/META-INF/resources 即可自動生效。

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