從web.xml開始
有的時候會困惑,web.xml到底是什么?為什么JavaEE要從web.xml開始呢?嗯,當把這個那個框架拋開,有些基礎的問題是非常有趣的。
web.xml不是必須的。你不用它一樣可以寫出web程序。
web.xml文件是用來配置:welcome、listener、servlet、filter等的。當你的web工程沒用到這些,你可以不寫web.xml文件。
進入正題。
Spring 提供 ServletContextListener 的一個實現類 ContextLoaderListener,該類可以作為 listener 使用,它會在創建時自動查找 WEB-INF/下的applicationContext.xrnl 文件。
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
如果有多個Spring配置文件需要載入,則考慮使用context-param。
由于ContextLoaderListener加載時,會查找名為contextConfigLocation的參數,配置context-param時參數名字應該是contextConfigLocation。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
Spring MVC 的Servlet,它將加載WEB-INF/123web-servlet.xml 的配置文件,以啟動Spring MVC模塊。
<servlet>
<servlet-name>123web</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>123web</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
session-timeout元素用來指定默認的會話超時時間間隔,以分鐘為單位。該元素值必須為整數。如果session-timeout元素的值為零或負數,則表示會話將永遠不會超時。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
404及welcome頁面:
<welcome-file-list>
<welcome-file>index.do</welcome-file>
</welcome-file-list>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
其中關于web.xml的一些有意思的細節問題:
@加載順序
加載順序與它們在 web.xml 文件中的先后順序無關。即不會因為 filter 寫在 listener 的前面而會先加載 filter。最終得出的結論是:listener -> filter -> servlet,同時還存在著這樣一種配置節:context-param,它用于向 ServletContext 提供鍵值對,即應用程序上下文信息。我們的 listener, filter 等在初始化時會用到這些上下文中的信息,那么 context-param 配置節是不是應該寫在 listener 配置節前呢?實際上 context-param 配置節可寫在任意位置,因此真 正的加載順序為:context-param -> listener -> filter -> servlet
@Mapping規則
當一個請求發送到servlet容器的時候,容器先會將請求的url減去當前應用上下文的路徑作為servlet的映射url,比如我訪問的是http://localhost/test/aaa.html,我的應用上下文是test,容器會將http://localhost/test去掉,剩下的/aaa.html部分拿來做servlet的映射匹配。這個映射匹配過程是有順序的,而且當有一個servlet匹配成功以后,就不會去理會剩下的servlet了(filter不同,后文會提到)。其匹配規則和順序如下:
1. 精確路徑匹配。例子:比如servletA 的url-pattern為 /test,servletB的url-pattern為 /* ,這個時候,如果我訪問的url為http://localhost/test ,這個時候容器就會先 進行精確路徑匹配,發現/test正好被servletA精確匹配,那么就去調用servletA,也不會去理會其他的servlet了。
2. 最長路徑匹配。例子:servletA的url-pattern為/test/*,而servletB的url-pattern為/test/a/*,此時訪問http://localhost/test/a時,容器會選擇路徑最長的servlet來匹配,也就是這里的servletB。
3. 擴展匹配,如果url最后一段包含擴展,容器將會根據擴展選擇合適的servlet。例子:servletA的url-pattern:*.action
@不同的映射
以”/’開頭和以”/*”結尾的是用來做路徑映射的。
以前綴”*.”開頭的是用來做擴展映射的。
所以,為什么定義”/*.action”這樣一個看起來很正常的匹配會錯?因為這個匹配即屬于路徑映射,也屬于擴展映射,導致容器無法判斷。

浙公網安備 33010602011771號