問題:服務器端mvc框架是怎麼接收請求的?
即:客戶端瀏覽器發出request請求,服務器收到請求,並將請求交給應用程序處理,之後把處理結果返回給客戶端作爲應答。
當我們輸入:192.168.0.100:8080/csdn/index.do時,ip地址定位到服務器所在的主機,8080端口定位到服務器(類似apache的軟件服務器),而csdn指向當前服務器下部署的某一應用,index.do則是具體的路由到哪個控制器。問題出在服務器到控制器間,也就是上圖A階段末期,應用程序怎麼才能接收到請求,並將具體請求分發路由到具體控制器讓它來解決並應答呢?
服務器有很多應用程序,通過url定位請求。每一個app中的mvc框架都會最終接收請求並分發到具體的控制器去執行。感覺像是對url一層一層的剝離,這樣符合網絡5層協議的精神!
所以,需要解答mvc怎麼樣將控制器映射起來,接受請求後又是怎麼樣找到它的這個問題。
php模式
在php中最簡單的方式是:直接定位處理請求的某個php,比如192.168.0.100:8080/csdn/doRequest.php?name=z&age=10,然後在該php文件中通過$_GET['name']獲取參數,進一步處理,最後返回結果。
在thinkPHP等框架中,有一個文件作爲集中請求分發的入口,然後每次發送請求時都需要指向該入口。thinkPHP一般是根目錄下的index.php,則沒有隱藏它的時候每次發送請求都需要帶上它作爲url一部分,比如192.168.0.100:8080/csdn/index.php/Login/login。該url指向Login模塊的login方法,入口是index.php,必須由他初始化加載thinkphp來解析url找到Login的login。
這種模式下,我們的url也清晰地指出了入口,指明由它處理,很好理解。
java模式
java中以spring爲例,tomcat等啓動時加載環境,並根據web.xml初始化部署在其下的所有web應用,而spring也就是在這時候初始化的,負責調度的是一個叫做DispatcherServlet的Servlet。
<web-app>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
假如有一個請求192.168.0.100:8080/csdn/hello.do,會由這個servlet來負責解析並調度hello.do,好像它就代表了csdn一樣,而我們的url並沒有它,它是如何接收請求的呢?
最開始用java編寫web是使用servlet,在web.xml配置如下:
<web-app>
...
// servlet註冊
<servlet>
<servlet-name>nameToRegister</servlet-name>
<servlet-class>com.csdn.Hello</servlet-class>
</servlet>
//servlet映射
<servlet-mapping>
<servlet-name>nameToRegister</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
...
</web-app>
服務器啓動時加載該文件,自然會初始化註冊該servlet,當請求192.168.0.100:8080/csdn/hello時就指向com.csdn.Hello類來處理。spring和原生servlet相似,不過原生servlet編程需在web.xml配置每一個servlet實現類及其映射,而spring把DispatcherServlet作爲總入口servlet,凡是符合它映射規則的請求都交由它處理。所以192.168.0.100:8080/csdn/hello.do會交給它,因爲符合“*.do”規則。在DispatcherServlet內部會對各種參數進行組合,然後再具體匹配“hello.do”實現類,由該實現類處理實際請求並返回結果。由此,java中的servlet及其url-pattern是在tomcat啓動時註冊好了的,8080端口由tomcat監聽,它負責找到csdn應用並通過url-pattern找到該應用下處理請求的servlet。一切早已就緒,靜靜的,只是等待用戶請求的到來。