js|servlet
路徑狀態測試
目的
測試jsp之間互相跳轉,servlet跳轉jsp環境下絕對路徑和相對路徑的狀態
尋找出一種通用的解決辦法
資源
打成的WAR包
MyWAR
組成檔案
JSP
a.jsp
b/
b.jsp
ccc.jsp
Servlet
TestServlet.java mapping: /layer1/layer2/TestServlet
流程描述
1. 由a.jsp直接跳轉到b.jsp
或
由a.jsp提交到TestServlet,TestServlet根據a的提交選擇相應跳轉方式(forward/sendRedirect)
然後跳轉到b.jsp
2. b.jsp包含一系列超鏈,來顯示不同方式的跳轉後超鏈的情況
/a.jsp
../a.jsp
../../a.jsp
../../../a.jsp
ccc.jsp
/b/ccc.jsp
../ccc.jsp
../b/ccc.jsp
../../ccc.jsp
../../b/ccc.jsp
../../../ccc.jso
../../../b/ccc.jsp
[contextPath]/b/b.jsp
測試結果
短語替換
http://localhost:8080/ => ip/
/MyWAR/ => war/
http://localhost:8080/MyWAR/ => ip/war/
/MyWAR => [contextPath] (request.getContextPath())
跳轉方式 直接跳轉<a ..> servlet/forward servlet/sendRedirect
requestDispatcher.forward response.sendRedirect
---------------------+---------------------+----------------------------------+------------------------
servlet中跳轉的路徑 x /b/b.jsp /war/b/b.jsp
---------------------+---------------------+----------------------------------+------------------------
跳轉後瀏覽器的地址欄 ip/war/b/b.jsp ip/war/layer1/layer2/TestServlet ip/war/b/b.jsp
---------------------+---------------------+----------------------------------+------------------------
b.jsp中的連結清單 瀏覽器狀態條出現的連結地址
<a href="這裡的描述"
---------------------+---------------------+----------------------------------+------------------------
/a.jsp ip/a.jsp ip/a.jsp ip/a.jsp
../a.jsp ip/war/a.jsp ip/war/layer1/a.jsp ip/war/a.jsp
../../a.jsp ip/a.jsp ip/war/a.jsp ip/a.jsp
../../../a.jsp ip/a.jsp ip/a.jsp ip/a.jsp
ccc.jsp ip/war/b/ccc.jsp ip/war/layer1/layer2/ccc.jsp ip/war/b/ccc.jsp
/b/ccc.jsp ip/b/ccc.jsp ip/b/ccc.jsp ip/b/ccc.jsp
../ccc.jsp ip/war/ccc.jsp ip/war/layer1/ccc.jsp ip/war/ccc.jsp
../b/ccc.jsp ip/war/b/ccc.jsp ip/war/layer1/b/ccc.jsp ip/war/b/ccc.jsp
../../ccc.jsp ip/ccc.jsp ip/war/ccc.jsp ip/ccc.jsp
../../b/ccc.jsp ip/b/ccc.jsp ip/war/b/ccc.jsp ip/b/ccc.jsp
../../../ccc.jsp ip/ccc.jsp ip/ccc.jsp ip/ccc.jsp
../../../b/ccc.jsp ip/b/ccc.jsp ip/b/ccc.jsp ip/b/ccc.jsp
[contextPath]/b/b.jsp ip/war/b/b.jsp ip/war/b/b.jsp ip/war/b/b.jsp
---------------------+---------------------+----------------------------------+------------------------
總結
由上面的列表看出,只有最下面一行是有實際意義而且無論以任何方式跳轉連結地址都是正確無誤的
1. 在jsp中的“/”表示的根為“ip”,不包含WAR路徑
2. 在servlet中以forward方式使用的“/”表示的根為“ip/war/”,包含了WAR路徑
3. 在servlet中以sendRedirect方式使用的“/”表示的根為ip,不包含WAR路徑
4. 在servlet中以forward方式跳轉,則瀏覽器的地址欄仍然為此servlet,不會改變
5. 在servlet中以sendRedirect方式跳轉,則瀏覽器的地址欄改變為目的路徑
6. 相對路徑的確定是以瀏覽器的地址欄顯示的路徑為基準的,而非具體的目錄結構,所以
跳轉到同目錄下的某個頁面使用<a href="檔案名稱">link</a>這種方式不是永久成立的
(做asp的人不要驚訝,這裡說的jsp和servlet :))
7. 為了避免jsp跳jsp,servlet跳jsp,forward方式跳轉,sendRedirect跳轉產生的路徑問題,
對於jsp和使用sendRedirect跳轉的servlet,採用直接使用帶
容器路徑[String request.getContextPath()]的絕對路徑就可以徹底解決,即:
1)<%
String contextPath = request.getContextPath();
String url = contextPath + "/user/login.jsp";
%>
<a href="<%=url%>"> login</a>
2) ....
String contextPath = request.getContextPath();
String targetPath = contextPath + "/user/login.jsp";
RequestDispatcher rd = request.getRequestDispatcher(targetPath);
rd.forward(request, response);
......
對於使用forward跳轉的servlet,則不要加容器路徑,否則就重複出現 容器路徑,原因參見 2
8. 如果使用的“../”過多也不會出現嚴重問題,“../”最多使連結到達“ip/”
9. 另外,在使用
<jsp:include page = "url" flush="true"/>
<%@ include file="url" %>
<%@ page errorPage = "url" %>時,
這裡url使用的“/”表示的根為“ip/war/”,包含了WAR路徑