1、基本概念的理解
絕對路徑:絕對路徑就是你的主頁上的文件或目錄在硬盤上真正的路徑,(URL和物理路徑)例如:C:\xyz\test.txt 代表了test.txt文件的絕對路徑。http://www.sun.com/index.htm也代表了一個URL絕對路徑。
相對路徑:相對與某個基准目錄的路徑。包含Web的相對路徑(HTML中的相對目錄),
在項目中,"/"代表Web站點的根目錄,"./"代表當前目錄, "../"代表上級目錄, http://www.cnblogs.com/代表上上級目錄,以此類推。
例如:C:\test\AC\下面有a.html和c.html, C:\test\B\下面有b.html,則在a.htm中訪問b.html絕對路徑為C:\test\B\b.html,相對路徑為../B/b.html;訪問c.html絕對路徑為C:\test\AC\c.html,相對路徑為./c.html或者c.html。
2、關於JSP/Servlet中的相對路徑和絕對路徑。
2.1 服務器端的地址
假設我們的項目訪問地址為:http://172.0.0.1/TestProject/
服務器端的相對地址指的是相對於你的web應用的地址,這個地址是在服務器端解析的(不同於html和javascript中的相對地址,他們是由客戶端瀏覽器解析的)也就是說這時候在jsp和servlet中的相對地址應該是相對於你的web應用,即相對於http://172.0.0.1/TestProject/的。
其用到的地方有:
forward:servlet中的request.getRequestDispatcher(address);這個address是在服務器端解析的,所以,你要forward到error.jsp應該這么寫:
request.getRequestDispatcher(“pages/error.jsp”),這個/相對於當前的web應用TestProject,其絕對地址就是:http://172.0.0.1/TestProject/pages/error.jsp。
sendRedirect:在jsp中<%response.sendRedirect("/pages/error.jsp ");
在Servlet中,如果要訪問WEB-INF下面的jsp頁面時,必須加上/WEB-INF這個路徑,因為Servlet的路徑是相對服務器端地址的,即http://172.0.0.1/TestProject/,例如:request.getRequestDispatcher("/WEB-INF/content/student-detail.jsp")
2.2客戶端的地址
所有的html頁面中的相對地址都是相對於服務器根目錄(http://172.0.0.1/)的,而不是(跟目錄下的該Web應用的目錄)http://172.0.0.1/TestProject/的。 Html中的form表單的action屬性的地址應該是相對於服務器根目錄(http://172.0.0.1/)的,所以,如果提交到error.jsp為:action="<%=request.getContextPath()%>/pages/error.jsp”;提交到servlet為action="<%=request.getContextPath()%>/handleservlet"; Javascript也是在客戶端解析的,所以其相對路徑和form表單一樣。
因此,一般情況下,在JSP/HTML頁面等引用的CSS,Javascript.Action等屬性前面最好都加上<%=request.getContextPath()%>,以確保所引用的文件都屬於Web應用中的目錄。另外,應該盡量避免使用類似".","./","http://www.cnblogs.com/"等類似的相對該文件位置的相對路徑,因為這樣當文件移動時,很容易出問題。
2.3 站點根目錄和系統目錄
站點根目錄:在Web項目中“/”是表示站點根目錄的相對路徑,例如在jsp頁面中引入<link rel="stylesheet" type="text/css" href="/css/style.css" />
<script type="text/javascript" src="/js/common.js"></script>,style.css和common.js的路徑分別為http://172.0.0.1/css/style.css和(http://172.0.0.1/js/common.js。因為/css/…. 是相對於站點根目錄(http://172.0.0.1/)的相對路徑。 這樣jsp是無法訪問到css或js文件的。
系統目錄:眾所周知,JSP是Servlet的一種特殊形式,每個JSP頁面就是一個Servlet實例——JSP頁面由系統編譯成Servlet,Servlet再負責響應用戶請求。JSP其實也是Servlet的一種簡化,使用JSP時,其實還是使用Servlet,因為Web應用中的每個JSP頁面都會由Servlet容器生成對應的Servlet。也就說jsp所在的目錄還是服務端目錄,即JSP地址還是相對系統根目錄http://172.0.0.1/TestProject/的。
也就是說站點根目錄為http://172.0.0.1/,系統根目錄為http://172.0.0.1/TestProject/,這跟客戶端地址和服務端地址是相似的。
3、在JSP中引用js/css/的兩種方式
第一種:站點根目錄下絕對路徑的方式
假設我們項目的URL為:http://172.0.0.1/TestProject/index.jsp。
為了在以后更改工程名時也能正確訪問,我們需要加 <%basePath=request.getContextPath() %>
如:<script src="<%=request.getContextPath() %> /js/common.js"></script>
寫<%=request.getContextPath() %>太麻煩,可以在每一個jsp文件頂部加入以下內容后,
- <%
- String path = request.getContextPath();
- String basePath = request.getScheme()+"://" +request.getServerName()+":"+request.getServerPort()+path+"/" ;
- %>
- <base href="<%=basePath%>" >
就可直接使用 <script src=" /js/common.js"></script>了。
第二種:系統根目錄下相對路徑的訪問方式
當在jsp中引入css/js時,如果其相對路徑相對於當前jsp文件的,而當前的jsp的相對路徑又是相對於系統目錄http://172.0.0.1/TestProject/的。
所以在上面的引入方式中去掉“/”即可。即<link rel="stylesheet" type="text/css" href="css/style.css" /><script type="text/javascript" src="js/common.js"></script>。在jsp頁面引入圖片也是如此<img src="images/succeed.png"/>。如果一定要使用站點根目錄的話就這樣使用<img src="<%=request.getContextPath()%>/images/succeed.png"/>,這兩種方式都是可以的。
4、在Servlet/Action中跳轉到相應的Jsp頁面的方式
第一種情況:假如jsp頁面是可以直接訪問到的,即是放在WEB-INF外面的,假設該jsp頁面訪問地址為http://172.0.0.1/TestProject/pages/test.jsp。則Servlet中通過request.getRequestDispatcher("/pages/test.jsp").forward(request, response)這種方式即可跳轉到test.jsp。
第二種情況:假如該jsp頁面是不可以直接訪問的,是在WEB-INF里面的。假設該jsp頁面所在的目錄為http://172.0.0.1/TestProject/WEB-INF/content/student-list.jsp。則Servlet中通過request.getRequestDispatcher("/WEB-INF/content/student-list.jsp").forward(request, response)跳轉。在Struts2中通過配置<result name="success">/content/student-list.jsp</result>即可訪問。
5、Forward、Redirect及Include的區別
首先,sendRedirect與forward,include的最大區別是request,response. sendRedirect產生新的請求與響應,服務器收到請求后發送一個狀態頭給客戶,客戶將再次請求,就有兩次網絡通行的來往。redirect是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器重新去請求那個地址.所以地址欄顯示的是新的URL.所以redirect等於客戶端向服務器端發出兩次request,同時也接受兩次response.所以redirect可以重定向到外部的資源,如:response.sendRedriect("http://www.baidu.com"); 當Servlet發送“http://www.baidu.com”到服務器時,服務器再將該地址返回客戶端,此時瀏覽器URL為“http://www.baidu.com”,然后客戶端再去訪問“http://www.baidu.com”這個地址。
其次,forward與include基本上都是轉發到context內部的資源。它們是服務器內部重定向,程序接收到請求后重新定向到另一個程序,而客戶端並不知曉。從地址欄顯示來說forward與include是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,然后把這些內容 再發給瀏覽器.瀏覽器根本不知道服務器發送的內容從哪里來的,所以它的地址欄還是原來的地址. forward與include會將 request state、bean、等信息帶到下一個jsp頁面;
使用getAttribute()來取得前一個jsp所放的信息,redirect 是送到客戶端后再次request,因此上一個jsp的信息不被保留。
最后,forward與include的區別就是,forward方法是把請求的內容轉發到另外的一個servlet。而include是把另一個servlet處理過后的內容拿過來.
使用方式:
1. sendRedirect
servlet和jsp里面一樣
response.sendRedirect();
2. include
1) servlet里面
request.getRequestDispatcher( "jsp2.jsp" ).include(request, response);
2) jsp里面
<jsp:include page= "include.jsp" />
3. forword
1) servlet里面
request.getRequestDispatcher( "jsp2.jsp" ).forward(request, response);
2) jsp里面
<jsp:forward page= "include.jsp" />