JSP、Servlet中的相對路徑和絕對路徑 頁面跳轉問題 (轉)


1.JSP、Servlet中的相對路徑和絕對路徑 

    前提:假設你的Http地址為http://192.168.0.1/你的web應用為test,path="/test"那么你的web應用URL為http://192.168.0.1/test/

    如果JSP,JS文件放在WEB-INF目錄下根本無法訪問的,JSP如果放在WEB-INF目錄下可以通過服務器內部轉向進行訪問(主要是為了頁面的安全),但是JS是通過客戶端向服務器請求的,所以圖片以及一些JS,CSS只能放在WEB-INF外面 。
  web應用的目錄結構:

   test/web/

     css/
     js/

        test.js

     web-inf/
       classes/
       lib/
       user/
         a.jsp
         b.jsp
       images/      
       web.xml
         <servlet-mapping>
           <servlet-name>handleservlet</servlet-name>
           <url-pattern>/handleservlet</url-pattern>此映射是相對於當前web應用的
         </servlet-mapping>
  所有相對路徑都是由"/"開頭的 。如:/image/a.gif,/user/main.jsp,大家知道在html中的相對路徑是這樣的:

  假如有個html文件:a.html,其中有<link href="one.css" rel="stylesheet" type="text/css">,其中href屬性表示引用的css文件的路徑。
     one.css:表示one.css和a.hmtl處於同一個目錄
     user/one.css:表示one.css處於a.html所在目錄的同級目錄user的子目錄中,即user是a.html在同一個目錄 。
    ../one.css:表示one.css位於a.hmtl上一級目錄下,
    ../../one.css:表示one.css位於a.hmtl上一級目錄的上一級目錄下,
    ./:表示和a.hmtl同一目錄 
  我們稱上述相對路徑為html相對路徑


  1、 服務器端的地址
  服務器端的相對地址指的是相對於你的web應用的地址這個地址是在服務器端解析的 (不同於html和javascript中的相對地址,他們是由客戶端瀏覽器解析的 )也就是說這時候在jsp和servlet中的相對地址應該是相對於你的web應用,即相對於http://192.168.0.1/test/的。
  其用到的地方有:
     forward:servlet中的request.getRequestDispatcher(address);這個address是在服務器端解析的,所以,你要forward到user/a.jsp應該這么寫:request.getRequestDispatcher("/user/a.jsp ")這個/相對於當前的web應用test,其絕對地址就是:http://192.168.0.1/test/user/a.jsp。
     redirect:在jsp中<%response.sendRedirect("/rtccp/user/a.jsp");%>

  2、 客戶端的地址
  所有的html中的相對地址都是相對於http://192.168.0.1/的,而不是http://192.168.0.1/test/的 。所以需要加上web應用工程名
  Html中的form表單的action屬性的地址應該是相對於http://192.168.0.1/的,所以,如果提交到user/a.jsp為:action="/test/ user/a.jsp" ;提交到servlet為action="/test/handleservlet"
  Javascript也是在客戶端解析的,所以其相對路徑和form表單一樣。

 
3、 站點根目錄和css路徑問題  (jsp是服務器端程序,地址是變化的,引用時一般用站點根目錄的相對路徑)
  我們稱類似這樣的相對路徑/test/…. 為相對於站點根目錄 的相對路徑 。
  當在jsp中引入css時,如果其相對路徑相對於當前jsp文件的,而在一個和這個jsp的路徑不一樣的servlet中forward這個jsp時,就會發現這個css樣式根本沒有起作用。這是因為在servlet中轉發時css的路徑就是相對於這個servlet 的相對路徑而非jsp的路徑了。所以這時候不能在jsp中用這樣的路徑:<link href="one.css" rel="stylesheet" type="text/css">或者<link href="../../one.css" rel="stylesheet" type="text/css">類似href="one.css"和../../one.css的html相對路徑是相對於引用這個css的文件(a.jsp)的相對路徑 。而在servlet中轉發時就是相對於這個servlet的相對路徑了,因為jsp路徑和servlet路徑是不一樣的 ,所以這樣的引用肯定是出錯的。
  所以這個時候,要用站點根目錄,就是相對於http://192.168.0.1/的目錄,以“/”開頭
  因此上述錯誤應更正為href=”/test/one.css” 類似的站點根目錄的相對目錄。這樣在servlet轉發后和jsp中都是相對於站點根目錄的相對路徑 ,就能正確使用所定義的css樣式了。

 

頁面跳轉問題:

 

Forward 高,  Redirect 低, 因為Redirect 的流程是這樣的,  request1  sent to server,  server return back to client, 然后

request2 then sent to server. 但是Forward 僅在server side處理, 對client side 是透明的. 由於Redirect 有兩次傳輸, 所以效率低.

范圍:
由於對request.setAttribute() 來說, 它攜帶的對象生存范圍只在request內, 所以Redirect 方式會導致request攜帶的對象丟失.

 

使用說明:

1. sendRedirect

     servlet和jsp里面一樣

     response.sendRedirect(); 

 

2. include  這種也是上面提到的forward形式,request的值會保存

    1)  servlet里面

    request.getRequestDispatcher( "jsp2.jsp" ).include(request,   response);  

    2)  jsp里面

    <jsp:include page= "include.jsp" />

說明
頁面會同時包含頁面1和頁面2的內容,地址欄不變。
使用request.setAttribute的內容,可以正常使用

 

3. forword

    1)  servlet里面

    request.getRequestDispatcher( "jsp2.jsp" ).forward(request,   response); 
    2)  jsp里面

    <jsp:forward page= "include.jsp" />

說明
頁面會是頁面2的內容,地址欄不變
使用request.setAttribute的內容,可以正常使用


3.JSP中用相對路徑引用JS,CSS文件的三種情況

  第一種情況 最常見的情況
   一個tomcat上都跑多個工程, 用工程名來區分
   因為我的的URL是 :http://localhost/工程名 /home/index.jsp
   多了一個工程名,所以要加 <%=request.getContextPath() %>
   如:<script src="<%=request.getContextPath() %> /home/test.js"></script>

  寫<%=request.getContextPath() %>太麻煩,可以在每一個jsp文件頂部加入以下內容后,

 

   Java代碼 
  1. <%   
  2. String path = request.getContextPath();   
  3. String basePath = request.getScheme()+"://" +request.getServerName()+":" +request.getServerPort()+path+"/" ;   
  4. %>   
  5. <base href="<%=basePath%>" > 

     就可直接使用 <script src=" /home/test.js"></script>了

 

   第二, 直接訪問jsp文件

   真實項目中, 一個tomcat上要是也跑了多個工程, 並用IP來區分
   url 是這樣的: http://localhost/home/index.jsp     注意這里,是直接訪問JSP文件(jsp文件不在web-inf下,可以直接訪問),不是servlet也不是struts 。
   test2.js 與index.jsp 放在同一文件夾下,下面用相對路徑來引入JS文件 是OK 的:
  <script src=test2.js></script>

   index.jsp可以找到test2.js文件

 

   第三種情況: servlet轉發到jsp(jsp在web-inf下,必須用servlet或action訪問)

   在第二情況的基礎上,一個tomcat上要是也跑了多個工程, 並用IP來區分。

   我們訪問的是servlet 或是struts的action , 再轉發到 index.jsp
    url 是: http://localhost/***.do

    url 是: http://localhost/index.action

    這里不是訪問JSP文件了

 

    下面是OK 的.
     <script src="/home/ test2.j”></script>

    test2.js 前面一定要有/home/

    實際項目中, 訪問 servlet或是struts的action最多, 所以這里要使用<script src=/home/test2.js></script>。

 

請求轉發和重定向的路徑區別

 

一、請求轉發與響應重定向的種類

 

   有兩種方式獲得Servlet 轉發對象(RequestDispatcher):一種是通過HttpServletRequest的getRequestDispatcher()方法獲得,一種是通過ServletContext的getRequestDispatcher()方法獲 得。

 

   Servlet 重定向的方法只有一種:HttpServletResponse的sendRedirect()方法。

 

這三個方法的參數都是一個URL形式的字符串,但在使用相對路徑或絕對路徑上有所區別。

 

二、請求轉發與響應重定向中路徑參數區別

 


 假設通過http://localhost/myApp/cool/bar.do 請求到達該方法所屬的Servlet。

 

  1、響應重定向   ◆ HttpServletResponse.sendRedirect(String)

 

    參數可以指定為相對路徑、絕對路徑或其它Web應用

 

    i:相對路徑response.sendRedirect("foo/stuff.do"),容器相對於原來請求URL的目錄加參數來生成完整的URL——http://localhost/myApp/cool/foo/stuff.do

 

    ii:絕對路徑response.sendRedirect("/foo/stuff.do"),容器相對於Web應用本身加參數建立完整的URL,這是因為  重定向response.sendRedirect("")是服務器向客戶端發送一個請求頭信息,由客戶端再請求一次服務器,請求是在服務  器外進行此時的"/"所代表的的根目錄並不包含工程名即完整的url是——http://localhost/foo/stuff.do

 

    iii:其它Web應用:response.sendRedirect("http://www.xxx.com ")容器直接定向到該URL。

 

  2、請求轉發    ◆HttpServletRequest.getRequestDispatcher(String)

 

    參數可以指定為相對路徑或絕對路徑

 

    i:相對路徑情況下生成的完整URL與重定向方法相同。

 

    ii:絕對路徑與Servlet重定向不同容器將相對於Web應用的根目錄加參數生成完整的URL(即“/”根路徑就是相對於虛擬路徑)這是因為轉發是在服務器內部進行的,寫絕對路徑/開頭指的是當前的Web應用程序

 

。即:

 

request.getRequestDispatcher("/foo/stuff.do")生成的URL是http://localhost/myApp/foo/stuff.do 。

 

   3、  ◆ ServletContext.getRequestDispatcher(String)

 

參數只能指定為絕對路徑生成的完整URL與HttpServletRequest.getRequestDispatcher(String)相同

 

 

 

##################################

 

同理:

 

JSP 提交表單給 Servlet 路徑問題

 

JSP頁面提交表單給Servlet時,路徑的寫法要格外注意。

例如在web.xml中注冊如下的servlet:

<servlet>
<servlet-name>addStudent</servlet-name>
<servlet-class>org.mytest.addStudent</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>addStudent</servlet-name>
<url-pattern>/servlet/addStudent</url-pattern>
</servlet-mapping>

假如說,你工程名字為HibernateApp3,JSP頁面提交表單給servlet時有兩種寫法:

1.相對路徑: <form action=servlet/addStudent  method=post>...</form>

2. 絕對路徑: <form action="/HibernateApp3/servlet/addStudent"  method=post>...</form>

  或者 <form action="<%=request.getContextPath() %>/servlet/addStudent"  method=post>...</form>

注意:/代表根目錄,如果路徑是使用/開頭,Tomcat就是webApp那個目錄,如果你不是/開頭代表你從當前工程的目錄開始,例如:webApp/HibernateApp3/

這一點非常重要,很多提交表單時發生的錯誤都是因為提交路徑出錯造成的。

 

附、<a href>的路徑如果是"/"開頭,則表示相對於主機,如果不是則表示相對於當前請求

綜上所述:這里最最關鍵的要能清楚 發出請求目的資源的請求是在服務器內部還是服務器外部:內部時,“/”就是項目的虛擬目錄;外部時,“/”就是代表主機的根目錄,請求轉發相當於服務器內部,

重定向則相當於服務器外部。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM