SpringMVC,3種不一樣的URL路由配置方法(這根本不是一個小問題)(轉)

SpringMVC中配置URL攔截,很是簡單。網上找個示例,就能經過。可是,在我作了好幾個Web項目,又參與了別人主導的Web項目時,發現URL配置也很是有學問。css

1. 先說說一種比較常見的:html

   

<servlet>java

<servlet-name>theDispatcher</servlet-name>web

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>正則表達式

<init-param>spring

<param-name>contextConfigLocation</param-name>spring-mvc

<param-value>classpath:spring/spring-mvc-servlet.xml</param-value>服務器

</init-param>mvc

<load-on-startup>1</load-on-startup>app

</servlet>

<servlet-mapping>

<servlet-name>theDispatcher</servlet-name>

<url-pattern>*.html</url-pattern>

</servlet-mapping>

 

讓SpringMVC指攔截 動態請求,js、css、img等靜態資源不通過Spring,直接讓Web容器處理。

 

若是配置了攔截器,也只會攔截.html動態請求。

 

靜態資源不走Spring,也不走攔截器,性能固然是比較好的。

若是使用了Nginx,配置靜態資源攔截,讓Nginx處理靜態資源的訪問。由於Nginx在處理靜態資源方面,比Tomcat等Web容器要強。

缺點:這種攔截動態請求的方法,比較死板。

2.  我本身常常有一種需求, http://FansUnion.cn/news 這種不指定.html後綴的其實也是 動態請求,因此我在配置url-pattern喜歡用「/」,即攔截全部的請求。URL是能夠靈活配置了,問題又來了,靜態資源再也不由Tomcat處理,因此必須在SpringMVC中再次配置,

 

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

讓SpringMVC把static靜態資源也處理了。顯然,讓SpringMVC處理靜態資源的性能沒有Tomcat直接處理比較高。

理論上,請求中轉的次數越多, 性能越差。

本覺得萬事大吉,雖然靜態資源的性能較低,至少程序能夠正常運行了,「反正是混過去了」。

進一步的需求,若是在Spring中配置了登陸等攔截器,這個時候也會把 靜態資源給攔截進來。

 

 

 

<mvc:resources mapping="/static/**" location="/static/" /> 這種URL映射,也沒法逃脫攔截器的魔爪。

 

 

我是怎麼發現這個問題的呢?

public class BaseLoginInterceptor extends HandlerInterceptorAdapter {

 

public boolean preHandle(HttpServletRequest request,

HttpServletResponse response, Object handler) throws Exception {

LoginUtil.setCurrentUser(null);

initCurrentUser(request, response);

HandlerMethod handlerMethod = (HandlerMethod) handler;

} 

公司的項目,Boss的登陸攔截器配置如上,「 HandlerMethod handlerMethod = (HandlerMethod) handler;

」。可是我在本身的項目中,發現這行代碼是有問題的。若是靜態資源被攔截到,會報錯:

java.lang.ClassCastException: org.springframework.web.servlet.resource.ResourceHttpRequestHandler cannot be cast to org.springframework.web.method.HandlerMethod

經過異常能夠發現,  Object handler是 ResourceHttpRequestHandler  ,而不是

HandlerMethod。

由於 

mvc:resources把靜態資源請求交給了 ResourceHttpRequestHandler

 

處理,所以強制轉換是有問題的。

 

公司項目中Boss的配置之因此沒有出現問題,是由於他配置的是隻攔截「.html」 動態請求,因此強制轉換老是成立的。

 

---------------------------------------------

咱們分析了上述兩種狀況, 發現「根本矛盾」「根本需求」是啥?

 

1.動態請求的URL應該很是靈活,/news /news.html都應該算做動態請求。

2.SpringMVC的url-pattern能夠配置 / , *.html,或者正則表達式,可是我不太喜歡用正則表達式。

3.若是可能,SpringMVC最好不要攔截靜態資源,讓Tomcat容器直接處理更好。

 

 

 

 

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

 

這是爲了性能考慮。

4.若是線上服務器配置了Nginx,我能夠選擇讓Nginx攔截靜態請求,由於比Tomcat處理性能更高。

 

本地是否配置Nginx,都不須要改動任何代碼。

-------------------------------------------------

上面說的 第一種方法的缺陷是,url配置不夠靈活。

 

第二種方法的缺陷是,SpringMVC要攔截靜態資源,並且登陸攔截器 也會攔截 靜態資源,不但性能差,程序還得再次修改,判斷HandlerMethod的實際類型。

 

3.終極解決方案: 

 

以我習慣用的第2種方法爲基礎,進一步改進:

去掉

 

 

 

 

 

 

<mvc:resources mapping="/static/**" location="/static/" />,不作靜態資源請求的映射。

在web.xml裏增長以下配置:

 

<servlet-mapping>

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

<url-pattern>/static/*</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>

激活Tomcat的defaultServlet來處理靜態文件。
相關文章
相關標籤/搜索