Spring MVC中處理靜態(tài)資源的多種方法

處理靜態(tài)資源,我想這可能是框架搭建完成之后Web開發(fā)的”頭等大事“了。

因?yàn)橐粋€(gè)網(wǎng)站的顯示肯定會依賴各種資源:腳本、圖片等,那么問題來了,如何在頁面中請求這些靜態(tài)資源呢?

還記得Spring MVC中的DispatcherServlet嗎?它是Spring MVC中的前置控制器,若配置的攔截路徑為“/”,那么所有的請求都將被它攔截。對靜態(tài)資源的訪問也屬于一個(gè)請求,那么也會被它攔截,然后進(jìn)入它的匹配流程,我們知道它是根據(jù)HandlerMapping的配置來匹配的。而對于靜態(tài)資源來說,默認(rèn)的Spring MVC是沒有注冊匹配規(guī)則的,此時(shí)若你去請求一個(gè)靜態(tài)資源,則會報(bào)404錯(cuò)誤。


如何處理靜態(tài)資源的請求呢?根據(jù)上面介紹的,我們可以配置一個(gè)處理靜態(tài)資源的HandlerMapping

《!--2,資源本地位置--》

<bean id="resourceHttpRequestHandler" class="org.springframework.web.servlet.resource.ResourceHttpRequestHandler">

????????<property name="locations" value="classpath:/META-INF/resources"></property>

</bean>

<!--1,處理鏈接-->

<bean??class="org.springframwork.web.servlet.handler.SimpleUrlHandlerMapping">??????

????? ?? <property name="mappings">

???????????????<props>

????????????????????<prop key="/resources/**">resourceHttpRequestHandler</prop>

????????????????</props>

????????</property>

</bean>

其中resourceHttpRequestHandler其中ResourceHttpRequestHandler就是處理靜態(tài)資源請求的類,當(dāng)然如果你愿意,也可以自己嘗試寫一個(gè)。不過現(xiàn)在這樣自己寫SimpleUrlHandlerMapping比較少了吧,項(xiàng)目中都是采用的注解配置,只不過是將匹配關(guān)系放到注解上另外,還可以使用mvc命名空間的resources標(biāo)簽來配置

<mvc:resources mapping="/resources/**" location="/resources/"/>

本質(zhì)上也是把ResourceHttpRequestHandler注冊到SimpleUrlHandlerMapping上。



還有別的方法來處理靜態(tài)資源請求嗎?Spring MVC還提供了一個(gè)配置項(xiàng):mvc:default-servlet-handler這個(gè)標(biāo)簽對于匹配規(guī)則為"/"的DispatcherServlet才生效(因?yàn)閯e的匹配規(guī)則一般也不會攔截靜態(tài)資源)。它會為DefaultServletHttpRequestHandler配置上"/**"的攔截規(guī)則和最低的匹配優(yōu)先級。DefaultServletHttpRequestHandler處理請求時(shí)會將其全部轉(zhuǎn)發(fā)到容器的DefaultServlet上。因此它在HandlerMapping必須是優(yōu)先級最低的。如果你使用或你使用了自定義的HandlerMapping實(shí)例,確保它們的order值比DefaultServletHttpRequestHandler?。↖nteger.MAX)。

另外需要注意的是,這里尋找容器的DefaultServlet是用名字而不是路徑。所以首先要搞清楚容器的DefaultServlet的名字,當(dāng)然一般主流容器的名字是無需指定的,比如Tomcat, Jetty, JBoss, and GlassFish等。若非常用容器,則可能需要手動(dòng)指定:

<mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>


這種方式也是依賴于容器的DefaultServlet的,那么我們是否能直接用容器的DefaultServlet來處理靜態(tài)資源請求,而不是這樣先通過Spring MVC來轉(zhuǎn)發(fā)呢?(相比性能上會好很多),答案是肯定的。

比如我們將資源文件都放在resouces目錄下,那么只需要在web.xml中配置:

<servlet-mapping>

????<servlet-name>default</servlet-name>

????<url-pattern>/resource/*</url-pattern>

</servlet-mapping>


并將它放在所有Servlet的最前面(為了讓它最先匹配),這樣的話性能上應(yīng)該比較好

但是這樣還會有個(gè)問題,就是無法訪問到classpath下的資源文件,看了tomcat的DefaultServlet的配置項(xiàng),似乎也沒有可以指定目錄的地方。

所以,綜上所述,性能最好的應(yīng)該是直接利用容器的DefaultServlet,讓它最先攔截靜態(tài)資源請求,這樣就避免了后續(xù)的轉(zhuǎn)發(fā)等操作,提高了性能,但是無法訪問classpath下的資源文件。而通過mvc:resources標(biāo)簽可以簡單配置匹配規(guī)則和資源文件路徑,應(yīng)該說是最簡單快捷的一種方式,當(dāng)然這大概也是mvc命名空間設(shè)計(jì)的初衷。

另外,若想結(jié)合兩者的話,自己倒是可以嘗試寫一個(gè)Servlet來處理,不過估計(jì)有難度且麻煩。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,578評論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,275評論 6 342
  • 這些屬性是否生效取決于對應(yīng)的組件是否聲明為 Spring 應(yīng)用程序上下文里的 Bean(基本是自動(dòng)配置的),為一個(gè)...
    發(fā)光的魚閱讀 1,489評論 0 14
  • 在我搭建基于Spring Cloud的微服務(wù)體系應(yīng)用的時(shí)候所需要或者是常用的屬性配置文件,還有這些屬性的用途,此配...
    StrongManAlone閱讀 4,302評論 0 18
  • 樂樂1006閱讀 112評論 0 0

友情鏈接更多精彩內(nèi)容