welcome-file-list
- <welcome-file-list>標(biāo)簽下可以設(shè)置多個首頁<welcome-file>,容器啟動后會在根目錄下依次查找匹配的物理存在的文件,返回第一個找到的文件,沒有找到報404錯誤。
<welcome-file-list>
<welcome-file>a.jsp</welcome-file>
<welcome-file>b.html</welcome-file>
<welcome-file>c.html</welcome-file>
</welcome-file-list>
- 首頁的路徑只能是一個實(shí)際存在的物理文件地址,不能將首頁設(shè)置成Servlet或Controller的地址,再通過來Servlet或Controller返回一個頁面,例如以下,tomcat會在根目錄下的view文件夾查找addUser文件,找不到則報404.
<welcome-file-list>
<welcome-file>/view/addUser</welcome-file>
</welcome-file-list>
如果確實(shí)需要使用控制器來返回頁面,可以通過在頁面中跳轉(zhuǎn)到控制器路徑來實(shí)現(xiàn)。建立首頁文件home.html,內(nèi)容如下,URL為跳轉(zhuǎn)路徑,再將該頁面設(shè)置為主頁
<html>
<head>
<meta http-equiv="Refresh" content="0; URL=/view/addUser">
</head>
</html>
- 可以不設(shè)置首頁,由SpringMVC來處理根路徑應(yīng)該返回的頁面,注意2中是設(shè)置首頁為控制器路徑,此處是不設(shè)置首頁,不要混淆。不設(shè)置首頁直接去掉welcome-file-list標(biāo)簽或者
<welcome-file-list>
<welcome-file></welcome-file>
</welcome-file-list>
對根路徑進(jìn)行映射
@RequestMapping("/")
public String indexPage() throws Exception {
return "index";
}
url-pattern匹配規(guī)則
- 需要明確
- servlet容器中的匹配規(guī)則既不是簡單的通配,也不是正則表達(dá)式,而是特定的規(guī)則。所以不要用通配符或者正則表達(dá)式的匹配規(guī)則來看待servlet的url-pattern。
- 當(dāng)servlet容器接收到瀏覽器發(fā)起的一個url請求后,容器會用url減去當(dāng)前應(yīng)用的上下文路徑,以剩余的字符串作為servlet映射,如url是http://localhost:8080/appDemo/addUser,其應(yīng)用上下文是appDemo,容器會將http://localhost:8080/appDemo去掉,用剩下的/addUser部分拿來做servlet的映射匹配
- 當(dāng)有一個servlet匹配成功以后,不會再繼續(xù)匹配剩下的servlet。
- Servlet 2.5開始,一個servlet可以使用多個url-pattern規(guī)則。以下3個url-pattern都可以映射到MyServlet
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/user/users.html</url-pattern>
<url-pattern>/index.html</url-pattern>
<url-pattern>/user/addUser.action</url-pattern>
</servlet-mapping>
- 三種寫法
- 精確匹配。形如/add。
注:/user//index也是精確匹配,其中的不是通配符而是字符。只有/user//index才能匹配上,/user/a/index,/user/b/index都是無法匹配的。 - 路徑匹配。形如/,/user/,以以/開頭,/*結(jié)尾
- 擴(kuò)展名匹配。形如*.do
注以上三種匹配不能組合混用。 - 默認(rèn)匹配/,當(dāng)以上都無法匹配時,就是用默認(rèn)的Servlert。優(yōu)先級最低
匹配優(yōu)先級
精確匹配>路徑匹配(長路徑優(yōu)先級大于短路徑優(yōu)先級)>擴(kuò)展名匹配>缺省匹配
- /* 與 /
“/* ”屬于路徑匹配,并且可以匹配所有request,由于路徑匹配的優(yōu)先級僅次于精確匹配,所以“/”會覆蓋所有的擴(kuò)展名匹配,很多404錯誤均由此引起,一般只用于filter的url-pattern。
“/”默認(rèn)匹配模式,優(yōu)先級最低,不會覆蓋其他任何url-pattern,只是會替換servlet容器的內(nèi)建default servlet ,該模式同樣會匹配所有request(除了jsp文件)。
配置“/”后,會攔截諸如http://localhost:8080/appDemo/user/addUser.action、http://localhost:8080/appDemo/user/updateUser的格式的請求,但是并不會攔截http://localhost:8080/appDemo/user/users.jsp、http://localhost:8080/appDemo/index.jsp,這是因?yàn)閟ervlet容器有內(nèi)置的“.jsp”匹配器,而擴(kuò)展名匹配的優(yōu)先級高于缺省匹配,所以才會有上述現(xiàn)象。
/*與/都會攔截.css,.js,.html等靜態(tài)資源。
如何訪問到靜態(tài)的文件,如jpg,js,css?
方案一:激活Tomcat的defaultServlet來處理靜態(tài)文件
<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>
特點(diǎn):1. 要配置多個,每種文件配置一個。
2. 要寫在DispatcherServlet的前面, 讓 defaultServlet先攔截請求,這樣請求就不會進(jìn)入Spring了。
3. 高性能。
備注:
Tomcat, Jetty, JBoss, and GlassFish 自帶的默認(rèn)Servlet的名字 -- "default"
Google App Engine 自帶的 默認(rèn)Servlet的名字 -- "_ah_default"
Resin 自帶的 默認(rèn)Servlet的名字 -- "resin-file"
WebLogic 自帶的 默認(rèn)Servlet的名字 -- "FileServlet"
WebSphere 自帶的 默認(rèn)Servlet的名字 -- "SimpleFileServlet"
方案二: 在spring3.0.4以后版本提供了<mvc:resources mapping="" location="" /> 使用方法:
<!-- 對靜態(tài)資源文件的訪問 -->
<mvc:resources mapping="/images/**" location="/images/" />
images/**映射到 ResourceHttpRequestHandler進(jìn)行處理,location指定靜態(tài)資源的位置.可以是web application根目錄下、jar包里面,這樣可以把靜態(tài)資源壓縮到j(luò)ar包中。cache-period 可以使得靜態(tài)資源進(jìn)行web cache
如果出現(xiàn)下面的錯誤,可能是沒有配置<mvc:annotation-driven />的原因。
報錯WARNING: No mapping found for HTTP request with URI [/mvc/user/findUser/lisi/770] in DispatcherServlet with name 'springMVC'
使用<mvc:resources/>元素,把mapping的URI注冊到SimpleUrlHandlerMapping的urlMap中,
key為mapping的URI pattern值,而value為ResourceHttpRequestHandler,
這樣就巧妙的把對靜態(tài)資源的訪問由HandlerMapping轉(zhuǎn)到ResourceHttpRequestHandler處理并返回,所以就支持classpath目錄,jar包內(nèi)靜態(tài)資源的訪問.
另外需要注意的一點(diǎn)是,不要對SimpleUrlHandlerMapping設(shè)置defaultHandler.因?yàn)閷tatic uri的defaultHandler就是ResourceHttpRequestHandler,
否則無法處理static resources request.
方案三 ,使用<mvc:default-servlet-handler/>
<mvc:default-servlet-handler/>
會把"/**" url,注冊到SimpleUrlHandlerMapping的urlMap中,把對靜態(tài)資源的訪問由HandlerMapping轉(zhuǎn)到 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler 處理并返回.
DefaultServletHttpRequestHandler使用就是各個Servlet容器自己的默認(rèn)Servlet.
補(bǔ)充說明:多個HandlerMapping的執(zhí)行順序問題:
DefaultAnnotationHandlerMapping的order屬性值是:0
< mvc:resources/ > 自動注冊的 SimpleUrlHandlerMapping 的order屬性值是: 2147483646
<mvc:default-servlet-handler/>自動注冊 的SimpleUrlHandlerMapping 的order屬性值是: [2147483647](http://zhidao.baidu.com/question/1883800724917404028.html?gossl=http%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3D2147483647%26tn%3D44039180_cpr%26fenlei%3Dmv6quAkxTZn0IZRqIHckPjm4nH00T1Y1nWmznWF-m1whrAmduW6v0ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6KdThsqpZwYTjCEQLGCpyw9Uz4Bmy-bIi4WUvYETgN-TLwGUv3EnH63n16snjTzPjbkP1fsPj0zr0)
spring會先執(zhí)行order值比較小的。當(dāng)訪問一個a.jpg圖片文件時,先通過 DefaultAnnotationHandlerMapping 來找處理器,一定是找不到的,因?yàn)槲覀儧]有叫a.jpg的Action。然后再按order值升序找,由于最后一個 SimpleUrlHandlerMapping 是匹配 "/**"的,所以一定會匹配上,就可以響應(yīng)圖片。 訪問一個圖片,還要走層層匹配。不知性能如何?
最后再說明一下,方案二、方案三 在訪問靜態(tài)資源時,如果有匹配的(近似)總攔截器,就會走攔截器。如果你在攔截中實(shí)現(xiàn)權(quán)限檢查,要注意過濾這些對靜態(tài)文件的請求。
如何你的DispatcherServlet攔截 *.do這樣的URL后綴,就不存上述問題了。還是有后綴方便。