其實這個路徑的問題應該不只是servelt,應該是整個項目里比如jsp的跳轉,超鏈接,都符合。
1 <body> 2 <h1>Servlet路徑跳轉</h1> 3 <hr> 4 <!--使用相對路徑訪問HelloServlet --> 5 <!-- /servlet/HelloServlet 第一個/表示服務器的根目錄 --> 6 <a href="servlet/HelloServlet">訪問HelloServlet!</a><br> 7 <!-- 使用絕對路徑 訪問HelloServlet,可以使用path變量:path變量表示項目的根目錄--> 8 <a href="<%=path%>/servlet/HelloServlet">訪問HelloServlet!</a><br> 9 <!--表單中action的URL地址寫法,與超鏈接方式完全相同。 --> 10 <a href="servlet/TestServlet">訪問TestServlet,跳轉到Test.jsp</a> 11 12 </body>
1. 相對路徑
<a href="servlet/HelloServlet">訪問HelloServlet!</a>。只所以這樣寫,是因為當前jsp和要訪問的servelt不在一個目錄下,所以要寫明所在的包:

(這里我不太理解的是,index.jsp其實是和src一個目錄等級,為什么不是寫src/servlet/HelloServlet?還是說src這樣項目自帶的文件夾是不需要寫明的?只需要些了包名/類名就是相對路徑?還是說index和src是一個層次,相對路徑就直接從下一個層次的servlet開始?)
超鏈接里servlet/HelloServelt前面不能有 反斜線,反斜線是代表服務器根目錄,"/servlet/HelloServlet"代表的地址是:
2. 絕對路徑
<a href="<%=path%>/servlet/HelloServlet">訪問HelloServlet!</a>里的path就是當前的上下文,表示項目的根目錄:
JSP開頭一般會有這兩句代碼:
<% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>
(我前面不知道哪里有認為相對路徑更靠譜,因為絕對路徑的話,發布出去的項目和自己電腦的代碼,絕對路徑不一樣。不過這么看的話,絕對路徑是獲取上下文,那倒是任何時候都靠譜了,怪不得項目的代碼里都是用path)
項目結構里index.jsp是在ServletPathDirection\WebRoot下面(ServletPathDirection是項目名)。但是打印這個path,值是項目名:ServletPathDirection。和WebRoot無關。
這么說的話,HelloServlet雖然在ServletPathDirection\src\servlet下面,但是實際的path是ServletPathDirection\servlet??
也就是說,獲取上下文路徑,項目創建時自帶的文件夾是無效的,不算路徑,只有自己創建的文件夾才算??
不對,這個上下文,就只是項目名,是項目的根目錄,HelloServlet獲取上下文,值也是ServletPathDirection??
那這樣的話,絕對路徑就是項目根目錄+自己創建的包/類??項目本身有的文件夾是不算的?
這么看的話,文件的物理路徑,和代碼里那個路徑就不是一個意思了,物理路徑一定是包含有src的:
/ServletPathDirection/src/servlet/HelloServlet.java
ps:
嘗試了幾次想要在servelt里打印一下路徑看看,但是一直寫不對。
剛剛看到,servelt輸出是到頁面,一直寫System.out是不行的,要寫HTML:
PrintWriter out=response.getWriter();//取得輸出流 out.println("<html>");//輸出的內容要放在HTML中 out.println("<body>"); out.println("要輸入的內容........."); out.println("</body>"); out.println("</html>");
好吧,還是沒做出來。
不過絕對路徑應該就是項目的根目錄+自己創建的那個文件路徑了,servlet絕對路徑的則是項目根目錄+<url-pattern>的值。
3. url方法
web.xml里注冊servlet時有寫其url:
<servlet-mapping> <servlet-name>TestServlet</servlet-name> <!--url-pattern處必須以/開頭,這里的/表示項目的根目錄 但是超鏈接里使用時,是不寫/的--> <url-pattern>/servlet/TestServlet</url-pattern> </servlet-mapping>
這里和上面不一樣,超鏈接里的 反斜線代表服務器的根目錄,所以超鏈接里使用servlet的url時,前面是不寫/的;url的反斜線代表的是項目的根目錄。
表單里的 action:“url” 寫法和超鏈接一致:
<a href="servlet/TestServlet">訪問TestServlet,跳轉到Test.jsp</a>
web.xml里的url是有 / 但是表單里 action后的url 是沒有 / 的。。
ps: 超鏈接方法servlet是直接是url,不帶前面的 反斜線,也不帶 .java.但是超鏈接訪問jsp就要寫 .jsp:
<a href="test.jsp">訪問Test.jsp</a>
此時,由當前頁面index.jsp訪問到了TestServlet.java。然后TestServlet的 doPost(){ 里面寫跳轉 }(doGet里面直接寫的是doPost,所以不管什么提交方式最后肯定是用doPost,但是超鏈接訪問也沒有寫是get還是post啊?(ps:超鏈接的默認請求方式是get,也能修改)):
//請求重定向方式跳轉到test.jsp,當前路徑是ServletPathDirection/servlet/
response.sendRedirect("test.jsp");
//使用request.getContextPath獲得上下文對象
response.sendRedirect(request.getContextPath()+"/test.jsp");
//服務器內部跳轉,這里的斜線表示項目的根目錄
request.getRequestDispatcher("/test.jsp").forward(request, response);
request.getRequestDispatcher("../test.jsp").forward(request, response);
第一種用重定向,地址就直接寫目標的名字,是在當前目錄下找test.jsp,找不到。Servlet的Java文件和jsp不在一級的目錄里。
第二句加上了上下文(其實就是項目根目錄),就補全了路徑(但如果jsp文件也在一個包下面呢?那也應該加上包名)
第三句用請求轉發, 反斜線代表是根目錄,路徑是對的
第四句的 ../ 也可以(這是回退到根目錄的意思還是 回退到上一級?)
ps:
./表示當前目錄
../表示父級目錄
/表示根目錄(超鏈接里是代表服務器的根目錄,所以超鏈接里是不寫 / ;表單的action訪問也是不寫。重定向里也是代表服務器根目錄。只有請求轉發里可以寫 / 代表項目根目錄)