在SpringMVC中,請求路徑前(針對於相對路徑)是否加上斜槓(/),會引起不同響應,從而對結果的正確性造成影響。這裏就記錄一下SpringMVC請求路徑中的斜槓問題


一.基本信息

1.web.xml中的<url-pattern>設置爲 /

<url-pattern>/</url-pattern>

2.spring-mvc.xml設置自定義視圖解析器

  1. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  2. <property name="prefix" value="/WEB-INF/jsp/"/>
  3. <property name="suffix" value=".jsp"/>
  4. </bean>

3.webapp文件目錄

  1. ├──pom.xml
  2. └──src
  3. └──main
  4. ├── java
  5. │ └──controller
  6. │ ├──HelloController.java
  7. │ └──WorldController.java
  8. ├── resources
  9. └── webapp
  10. ├── static
  11. │ └── img
  12. │ └──hello.png
  13. ├── WEB-INF
  14. │ ├── web.xml
  15. │ └── jsp
  16. │ ├── hello
  17. │ │ └── hello.jsp
  18. │ └── world
  19. │ └── world.jsp
  20. ├── index.jsp
  21. └── 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如下:

  1. HelloController.java ---> @RequestMapping("/hello/hello")
  2. 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!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章