初學jsp+servlet時經常碰上的幾個錯誤:404、路徑正確但頁面沒有任何內容、樣式和圖片丟失。
這幾個錯誤曾經讓我在debug時頭大,現在總結一下,其實它們都跟路徑有關,正是因為沒有處理好路徑跳轉的問題,才引發了這一連串的錯誤。
首先要說明的是:我們的頁面本來是沒有問題的,導致問題發生的是路徑跳轉。
那么,使我們的URL路徑跳轉的操作有哪些呢?
大概有以下幾種:
1、客戶端實現的跳轉(如html里的<a>標簽和表單提交、js里的window.location.href)
2、request.getRequestDispatcher
3、response.sendRedirect
那么這些路徑跳轉方式有什么不同呢?
首先是客戶端實現的跳轉:
?
客戶端實現的跳轉最不容易出現問題,
但值得注意的是“/”代表的不是項目的根路徑而是tomcat里指定的根路徑(默認在webapps/ROOT下)
注意:urlPatterns里的“/”除外,urlPatterns里的“/”指的是項目的根目錄!
所以要用request.getContextPath()來獲取項目的根路徑
如下:
<%@?page?contentType="text/html;charset=UTF-8"?language="java"?%>
<html>
<head>
<style type="text/css">
#p1 {
height: 20%;
width: 20%
}
</style>
</head>
<body>
<a href="<%=request.getContextPath()%>/servlet/AddServlet">click</a>
<img id="p1" src="<%=request.getContextPath()%>/spic/img9.jpg"/>
</body>
</html>
絕對路徑這么麻煩,那么為什么不用相對路徑呢?理由如下:
使用request.getContextPath()還有一點重要原因,在服務器內部(request.getRequestDispatcher)跳轉后,頁面對應URL路徑會發生變化,而此時若再以相對路徑去請求資源很可能請求不到需要的資源,此時就會發生樣式和圖片丟失的問題。
服務器內部跳轉(request.getRequestDispatcher)
?
以這種方式實現的跳轉在服務器內部運行,不會經過客戶端的處理,對應的URL路徑不會發生變化,究其原因是因為http的特性只允許客戶端發起的請求重新定位URL路徑。因此,即使在servlet里用request.getRequestDispatcher跳轉到其它路徑,實際上其路徑并不會發生改變,可以簡單的理解為把本來要跳轉到路徑的資源移到原路徑下運行。
可以看出如果我們在servlet里跳轉到另一個servlet或jsp頁面時,其路徑還是原路徑。
?
值得注意的是:
因為在服務器內部跳轉后需要request和response對象才能進行后續操作,因此需要forward(request,response),如果沒有forward就會出現頁面沒有任何內容的錯誤,因為沒有獲取request,不能進行后續操作。
請求重定向(response.sendRedirect)
當在servlet里用請求重定向時,實際上是返回給客戶端信息,讓客戶端重新發一次http請求給指定的資源,因此才實現路徑的跳轉。
這樣可以真正實現路徑的跳轉,也不容易出現資源錯誤,但也因為重新進行的http請求(http的無狀態性),使request里保存的數據不能傳遞,數據只能通過“........?a=1&b=flypie”這種形式寫在URL里。