Spring MVC DispatcherServlet 預設攔截所有請求(/ 或 *.do),導致靜態資源(CSS、JS、圖片)也進入 Spring 處理流程,造成 404 或效能浪費。需配置靜態資源直接由 Servlet 容器處理。
<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>
關鍵點:
DispatcherServlet 映射之前,讓 defaultServlet 先攔截。default;WebLogic → FileServlet;WebSphere → SimpleFileServlet;Resin → resin-file;GAE → _ah_default。<mvc:resources>(推薦)<mvc:resources mapping="/images/**" location="/images/" cache-period="31536000"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
屬性解析:
mapping:請求路徑模式,對應 ResourceHttpRequestHandler。location:資源實際位置,支援 classpath:、file:、jar: 協定。cache-period:秒數,啟用瀏覽器快取(HTTP Header Cache-Control)。優點:支援 JAR 內資源、快取控制、路徑映射靈活;缺點:請求仍經 Spring HandlerMapping,略有效能開銷。
<mvc:default-servlet-handler/&code>(最簡潔)<mvc:default-servlet-handler/>
原理:向容器預設 Servlet 轉發靜態資源請求。自動註冊 SimpleUrlHandlerMapping (order=Integer.MAX_VALUE) + DefaultServletHttpRequestHandler。
優點:零配置映射副檔名;缺點:同樣經 Spring 處理鏈,且若有全域攔截器需自行排除靜態路徑。
| HandlerMapping | Order 值 | 說明 |
|---|---|---|
| DefaultAnnotationHandlerMapping | 0 | 最優先,處理 @Controller |
<mvc:resources> 產生 | 2147483646 | 靜態資源映射 |
<mvc:default-servlet-handler> 產生 | 2147483647 | 兜底轉發容器預設 Servlet |
請求先嘗試 Controller 映射 → 失敗才落入靜態資源處理。若靜態資源量大,建議方案一或 Nginx 直接代理。
方案二、三的請求會通過 HandlerInterceptor。若攔截器做權限檢查,需排除靜態路徑:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/images/**"/>
<mvc:exclude-mapping path="/js/**"/>
<mvc:exclude-mapping path="/css/**"/>
<bean class="com.example.AuthInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
或在攔截器內判斷 request.getRequestURI() 開頭路徑直接 true 放行。
<mvc:resources> 靈活且支援 JAR 內資源。<mvc:default-servlet-handler/> 最省事。*.do 或 /api/* 避開靜態資源衝突。