一.基本信息
1.web.xml中的<url-pattern>設置爲 /
<url-pattern>/</url-pattern>
2.spring-mvc.xml設置自定義視圖解析器
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/WEB-INF/jsp/"/>
- <property name="suffix" value=".jsp"/>
- </bean>
3.webapp文件目錄
- ├──pom.xml
- └──src
- └──main
- ├── java
- │ └──controller
- │ ├──HelloController.java
- │ └──WorldController.java
- ├── resources
- └── webapp
- ├── static
- │ └── img
- │ └──hello.png
- ├── WEB-INF
- │ ├── web.xml
- │ └── jsp
- │ ├── hello
- │ │ └── hello.jsp
- │ └── world
- │ └── world.jsp
- ├── index.jsp
- └── index1.jsp
二.關於請求路徑
1.一個正確請求路徑能獲取一個服務器的資源,故請求路徑由資源路徑和資源名稱組成(即請求路徑=資源路徑+資源名稱)。
例如:http://localhost:8080/springmvc/test/hello,其中http://localhost:8080/springmvc/test爲資源路徑,hello爲資源名稱(故最後一個斜槓分開了資源路徑和資源名稱)。
2.請求路徑分爲絕對路徑和相對路徑
比如http://localhost:8080/springmvc/test/hello就是一個絕對路徑(完整路徑),能準確定位一個資源;
比如test/hello或者/test/hello就是一個相對路徑,它會依賴於一個其他路徑作爲參照路徑,與這個參照路徑組合去定位一個資源。那麼相對路徑最終會轉換爲一個絕對路徑去定位資源(參照路徑+相對路徑===>絕對路徑)。
3.相對路徑前是否加上斜槓(/),會有不同的結果。這裏就是要討論的主要問題。因爲絕對路徑是一個完整路徑,所以不存在這個問題。
4.如果路徑解析在前臺,那麼根路徑爲http://localhost:8080/
5.如果路徑解析在後臺,那麼根路徑爲http://localhost:8080/項目名/
三.因爲斜槓引起的疑慮
項目名爲springmvc,controller如下:
- HelloController.java ---> @RequestMapping("/hello/hello")
- WorldController.java ---> @RequestMapping("/world/world")
1.前臺路徑解析:開頭不帶斜槓的相對路徑
相對路徑前不帶斜槓時,開頭的路徑表示該路徑爲當前資源路徑的一個子路徑。
1.1 如果在項目首頁即頁面地址爲http://localhost:8080/springmvc/
此時當前路徑爲http://localhost:8080/springmvc/(即參照路徑爲http://localhost:8080/springmvc/),相對路徑爲hello/hello。那麼最終轉換的路徑爲http://localhost:8080/springmvc/hello/hello。這樣就會匹配到@RequestMapping("/hello/hello")
1.2 如果在項目其他頁面即頁面地址爲http://localhost:8080/springmvc/hello/hello
此時當前路徑爲http://localhost:8080/springmvc/hello/hello(即參照路徑(資源路徑)爲http://localhost:8080/springmvc/hello/),相對路徑爲world/world。那麼最終轉換的路徑爲http://localhost:8080/springmvc/hello/world/world,將無法匹配到任意@RequestMapping從而報404錯誤。原因是相對路徑前不帶斜槓時,開頭的路徑表示該路徑爲當前資源路徑的一個子路徑。
解決辦法1:在相對路徑前加上 /項目名,地址最終會轉爲爲http://localhost:8080/springmvc/world/world。如果項目名變化,這種方法就會失效。
解決方法2:使用JSP內置對象組成路徑即在相對路徑前加上 ${pageContext.request.contextPath}/, 地址最終會轉爲爲http://localhost:8080/springmvc/world/world。
2.前臺路徑解析:開頭不帶斜槓的相對路徑
相對路徑前帶斜槓時,開頭的路徑表示該路徑爲根路徑的一個子路徑,那麼參照路徑爲http://localhost:8080/(即爲前臺根路徑)。
如果相對路徑爲/hello/hello,那麼最終轉換的路徑爲http://localhost:8080/hello/hello,而無法匹配到任何@RequestMapping
(tips:由於設置自定義視圖解析器,所有需要使用forward或者redirect跳過自定義視圖解析器)
3.後臺路徑解析:開頭不帶斜槓的相對路徑
同前臺開頭不帶斜槓的相對路徑一樣,相對路徑前不帶斜槓時,開頭的路徑表示該路徑爲當前資源路徑的一個子路徑 。
在後臺,一般認爲是在controller(比如HelloController),那麼此時的參考路徑爲http://localhost:8080/springmvc/hello
3.1 如果重定向/轉發到controller,重定向/轉發地址爲 redirect:helloworld/helloworld 或者 forward:helloworld/helloworld
那麼最終請求路徑http://localhost:8080/springmvc/hello/helloworld/helloworld,而無法匹配到任何@RequestMapping
如果是轉發,地址欄還是顯示的開始的請求路徑;如果是重定向,則地址欄顯示的是這個新地址
3.2 如果重定向/轉發到jsp(只能是非WEB-INF內的jsp),重定向/轉發地址爲 redirect:index1.jsp 或者 forward:index1.jsp
那麼最終請求路徑http://localhost:8080/springmvc/hello/index1.jsp,找不到index1.jsp
如果是轉發,地址欄還是顯示的開始的請求路徑;如果是重定向,則地址欄顯示的是這個新地址
4.後臺路徑解析:開頭帶斜槓的相對路徑
同前臺開頭帶斜槓的相對路徑一樣,相對路徑前帶斜槓時,開頭的路徑表示該路徑爲根路徑的一個子路徑 。那麼參照路徑爲http://localhost:8080/springmvc/(即爲後臺根路徑)。
4.1如果重定向/轉發到controller,重定向/轉發地址爲 redirect:/helloworld/helloworld 或者 forward:/helloworld/helloworld
那麼最終請求路徑http://localhost:8080/springmvc/helloworld/helloworld,而匹配到@RequestMapping("/helloworld/helloworld")
如果是轉發,地址欄還是顯示的開始的請求路徑;如果是重定向,則地址欄顯示的是這個新地址
4.2 如果重定向/轉發到jsp(只能是非WEB-INF內的jsp),重定向/轉發地址爲 redirect:/index1.jsp 或者 forward:/index1.jsp
那麼最終請求路徑http://localhost:8080/springmvc/index1.jsp,定位到index1.jsp
如果是轉發,地址欄還是顯示的開始的請求路徑;如果是重定向,則地址欄顯示的是這個新地址
四:結論
1.相對路徑前不帶斜槓時,開頭的路徑表示該路徑爲當前資源路徑的一個子路徑
2.相對路徑前帶斜槓時,開頭的路徑表示該路徑爲根路徑的一個子路徑
3.前臺根路徑爲http://localhost:8080/(路徑在前臺,就在前臺解析)
4.後臺更路徑爲http://localhost:8080/springmvc/(路徑在後臺,就在後臺解析)
如果有錯誤,歡迎各位來拍磚,技術開源,相互指導,我們一起進步!Coding in Life, Making Life Better!