JavaWeb(七)之詳解JavaWeb路徑


前言

  在我們的實際開發中,經常要寫路徑,不管是鏈接,重定向還是轉發,這都是需要路徑的。那這一篇我給大家詳細的分享一下Web中的各種路徑問題。

  世界上一切東西都是相對的,對於這點而言,相信大家並不陌生,由於這篇文章是針對於WEB階段來講的,所以以下絕對路徑和相對路徑都是針對於整個互聯網而言的

  在JavaWeb中需要寫的路徑大概分為四大類:

    1)客戶端路徑

      超鏈接、表單、重定向

    2)服務端路徑

      轉發、包含

    3)獲取資源路徑

      servletContext獲取資源、ClassLoader獲取資源、Class獲取資源

    4)<url-pattern>路徑

  在本文中使用下圖構建Web項目的目錄:

    

一、客戶端路徑

  客戶端路徑是指運行在瀏覽器上的路徑。

  比如:表單、超鏈接、js(location.href)、Ajax(url)、CSS和JS的引入以及重定向等。路徑分為絕對路徑和相對路徑,相對路徑又分為相對主機的路徑和相對於當前請求的路徑。

1.1、超鏈接 

  超鏈接有三種書寫路徑的方式
    1)絕對路徑
    2)以"/"開頭的相對路徑
    3)不以"/"開頭的相對路徑

<%@ page language="java" contentType="text/html; charset=UTF-8"  
    pageEncoding="UTF-8"%>  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
<title>頁面A</title>  
</head>  
<body>  
    <!--   
        超鏈接有三種書寫路徑的方式  
            1,絕對地址    
            2,以"/"開頭的相對地址  
            3,不以"/"開頭的相對地址   
    -->  
    <!-- 1.絕對地址   -->  
        <!-- 完整的URL -->  
    <a href="http://localhost:8080/javaee/jsp/b.jsp">這是絕對地址超鏈接</a><br/>  
      
    <!-- 2.以"/"開頭的相對地址    -->  
        <!-- /代表了整個web項目,即:http://localhost:8080/ -->  
    <a href="/javaee/jsp/b.jsp">這是以"/"開頭的相對地址超鏈接</a><br/>  
      
    <!-- 3.不以"/"開頭的相對地址   -->  
        <!--   
            不以/開頭,則相對於當前資源的路徑  
            當前資源的路徑為:http://localhost:8080/javaee/jsp/  
            而b.jsp也在此路徑下  
            所以直接書寫b.jsp  
         -->  
    <a href="b.jsp">這是不以"/"開頭的相對地址超鏈接</a><br/>  
</body>  
</html>  

  分析:   

  1)絕對路徑(以協議開頭的路徑):最終請求路徑為:http://localhost:8080/javaee/jsp/b.jsp

  2)相對路徑:

    2.1) 相對於主機的路徑(以“/”開頭):相對於當前主機(可以簡單理解為ip地址,如果想深入了解請研究tomcat的Server.xml文件。這里是localhost)的路徑,請求的最終路徑為:http://localhost:8080/javaee/jsp/b.jsp

          2.2)相對於請求的路徑(不以“/”開頭):相對於當前請求(瀏覽器的請求)的路徑。

1.2、表單

  表單有三種書寫路徑的方式 
    1)絕對路徑
    2)以"/"開頭的相對路徑 
    3)不以"/"開頭的相對路徑    

<%@ page language="java" contentType="text/html; charset=UTF-8"  
    pageEncoding="UTF-8"%>  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
<title>Insert title here</title>  
</head>  
<body>  
    <!-- 表單提交到jsp中 -->  
    <!--   
        表當提交路徑有三種書寫方式   
            1,絕對地址    
            2,以"/"開頭的相對地址  
            3,不以"/"開頭的相對地址   
    -->  
    <form action="http://localhost:8080/javaee/jsp/b.jsp" methoe="get">  
        username:<input type="text" name="username" value="">  
        <input type="submit" value="提交---絕對地址    ">  
    </form>  
    <!--   
        以/開頭的相對地址     
        此時的/代表整個web項目,即:http://localhost:8080/  
    -->  
    <form action="/javaee/jsp/b.jsp" methoe="get">  
        username:<input type="text" name="username" value="">  
        <input type="submit" value="提交---以/開頭的相對地址">  
    </form>  
      
    <form action="b.jsp" methoe="get">  
        username:<input type="text" name="username" value="">  
        <input type="submit" value="提交---不以/開頭的相對地址 ">  
    </form>  
      
    <!-- 表單提交到Servlet -->  
    <!--   
        表單提交到Servlet有三種書寫方式  
        1,絕對路徑  
        2,以"/"開頭的相對地址  
        3,不以"/"開頭的相對地址   
    -->  
    <!-- 1.絕對地址   -->  
        <!-- 完整的URL -->  
    <form action="http://localhost:8080/javaee/PathServlet" methoe="get">  
        username:<input type="text" name="username" value="">  
        <input type="submit" value="表單提交到Servlet---絕對地址">  
    </form>  
      
    <!-- 2.以/開頭的相對地址  -->  
        <!-- 此時的/代表整個web項目,即:http://localhost:8080/  -->  
    <form action="/javaee/PathServlet" methoe="get">  
        username:<input type="text" name="username" value="">  
        <input type="submit" value="表單提交到Servlet---以/開頭的相對地址">  
    </form>  
    <!-- 3.不以/開頭的相對地址    -->  
        <!--   
            不以/開頭的相對路徑是相對於當前資源的路徑  
            此時form.jsp的地址為:http://localhost:8080/javaee/jsp/form.jsp  
            所以當前資源路徑為:http://localhost:8080/javaee/jsp  
            而要提交的Servlet的路徑為Http://localhost:8080/javaee/PathServlet  
            所以路徑為當前路徑的上一級路徑下  
            即路徑為:../PathServlet 注:.代表當前路徑 ..代表當前路徑的上一級路徑  
        -->  
    <form action="../PathServlet" methoe="get">  
        username:<input type="text" name="username" value="">  
        <input type="submit" value="表單提交到Servlet---不以/開頭的相對地址">  
    </form>  
</body>  
</html>  

 1.3、重定向

  表單有三種書寫路徑的方式 
    1)絕對路徑
    2)以"/"開頭的相對路徑 
    3)不以"/"開頭的相對路徑

  注意:在這里中我們一般只會用相對路徑,不會去用絕對路徑

import java.io.IOException;  
  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  

public class RedirectServlet extends HttpServlet {  
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        response.sendRedirect("http://localhost:8080/javaee/jsp/b.jsp");  
        /* 
         * 2.以"/"開頭的相對路徑 
         *      此時,/代表整個web工程的路徑,即http://localhost:8080/ 
         */  
//      response.sendRedirect("/javaee/jsp/b.jsp");  
        /* 
         * 3.不以"/"開頭的相對路徑 
         *      此時是相對於當前資源的相對路徑 
         *      當前資源路徑為:http://localhost:8080/javaee/RedirectServlet 
         *      即表示:RedirectServlet在路徑http://localhost:8080/javaee之下 
         *      而b.jsp在http://localhost:8080/javaee/jsp/b.jsp 
         *      所以最終地址寫為:jsp/b.jsp 
         */  
//      response.sendRedirect("jsp/b.jsp");  
          
    }  
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        doGet(request, response);  
    }  
  
}  

二、服務端路徑

  服務端路徑是指在服務器上面運行的請求,比如請求轉發(常用)、請求包含等。服務端的路徑有兩種:相對於當前應用的路徑和相對於當前請求的路徑。  

 2.1、請求轉發

  請求轉發有兩種書寫路徑的方式 
    2)以"/"開頭的相對路徑 
    3)不以"/"開頭的相對路徑

  注意:服務器端的路徑不能是絕對路徑,只能是相對路徑,也分為以/開頭和不以/開頭兩種 

import java.io.IOException;  
  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
/* 
 *      1.以"/"開頭的相對路徑 
 *      2.不以"/"開頭的相對路徑 
 */  
public class DispatcherServlet extends HttpServlet {  
  
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        /* 
         * 1.以"/"開頭的相對路徑 * 此時,/代表當前web項目,即:http://localhost:8080/javaee 
         */  
//      request.getRequestDispatcher("/jsp/b.jsp").forward(request, response);  
        /* 
         * 2.不以"/"開頭的相對路徑 
         *      相對於當前資源的相對路徑 
         *  此時,當前資源的路徑為:http://localhost:8080/javaee/DispatcherServlet 
         *  所以要轉發去的資源的路徑以:http://localhost:8080/javaee開頭 
         */  
        request.getRequestDispatcher("jsp/b.jsp").forward(request, response);  
    }  
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        doGet(request, response);  
    }  
  
} 

 

  注意:所有Web層框架的底層使用的都是Web的基礎Filter(Struts)或Servlet(SpringMVC),請求都是request,響應都是response,所以各個Web層框架的轉發或重定向底層都是利用request和response進行的。

2.2、請求包含

  請求包含和上面的請求轉發路徑方式一樣的

import java.io.IOException;  
  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
/* 
 * 請求包含不能書寫絕對地址,只能書寫相對地址 
 *      1.以"/"開頭的相對路徑 
 *      2.不以"/"開頭的相對路徑 
 */  
public class IncludeServlet extends HttpServlet {  
  
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        /* 
         * 1.以"/"開頭的相對路徑 
         *      此時,/代表當前web項目,即:http://localhost:8080/javaee 
         */  
//      request.getRequestDispatcher("/jsp/b.jsp").include(request, response);  
        /* 
         * 2.不以"/"開頭的相對路徑 
         *      相對於當前資源的相對路徑 
         *  此時,當前資源的路徑為:http://localhost:8080/javaee/IncludeServlet 
         *  所以要轉發去的資源的路徑以:http://localhost:8080/javaee開頭 
         */  
        request.getRequestDispatcher("jsp/b.jsp").include(request, response);  
    }  
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        doGet(request, response);  
    }  
  
}  

三、資源獲取路徑

  獲取資源的路徑主要有3種,分別是ServletContext、Class和ClassLoader。其中ServletContext是WEB階段的,Tomcat提供的一種獲取資源的方式;Class和ClassLoader獲取資源主要是JavaAPI提供的一種獲取流的方式

  由於這是JDK提供的,所以不僅局限於Web,在普通Java類中也可以使用,主要用於獲取src目錄及其子目錄下的文件流。

3.1、ServletContext獲取資源

  這里ServletContext獲取資源的路徑是相對系統的絕對路徑(在Windows中是帶盤符的,可以用來獲取上傳或下載文件的具體路徑)

  基本語法:servletContext.getRealPath("路徑");參數中的路徑必須是相對路徑,可以“/”開頭,也可以不使用“/”開頭,但無論是否使用“/”開頭都是相對當前應用路徑,建議以"/"開頭(這樣可以盡量統一)。

  另外獲取ServletContext的方法如下:
    1)使用request獲取: request.getSession().getServletContext();
    2)在Servlet中獲取:this.getServletContext();
    3)使用FilterConfig對象獲取(在Filter中使用):config.getServletContext();

   ServletContext獲取資源必須是相對路徑,不能是絕對路徑,但不管是以/開頭,還是不以/開頭, 都是相對於當前資源的相對路徑 。  

import java.io.IOException;  
import java.io.InputStream;  
import java.util.Properties;  
  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  

public class ServletContextServlet extends HttpServlet {  
  
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        String path1 = this.getServletContext().getRealPath("/a.properties");  
        String path2 = this.getServletContext().getRealPath("a.properties");  
        System.out.println(path1);  
        System.out.println(path2);  
        //輸出的地址一樣  
    }  
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        doGet(request, response);  
    }  
  
}  

 3.2、ClassLoader獲取資源 

  和Class獲取資源類似。只是不同的寫法而已,也是用於獲取文件流的

  用法:classLoader.getResourceAsStream("路徑")。參數中的路徑可以以“/”開頭,也可以不以“/”開頭(建議)。但帶不帶“/”的都表示相對於當前類的路徑。

  ClassLoader類加載器不能通過絕對地址來加載資源,只能通過相對地址來加載資源  但相對地址不管前面加不加/都是相當於類路徑的相對地址  

public class ClassLoaderServlet extends HttpServlet {  
  
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        /* 
         * 加了/,其地址是相對於類路徑的相對地址 
         */  
//      InputStream in = this.getClass().getClassLoader().getResourceAsStream("/cn/ccnu/classloaderpath/c.properties");  
//      Properties prop = new Properties();  
//      prop.load(in);  
//      System.out.println(prop.getProperty("url"));  
          
        /* 
         * 不加/,其地址是相對於類路徑的相對地址 
         */  
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("cn/ccnu/classloaderpath/c.properties");  
        Properties prop = new Properties();  
        prop.load(in);  
        System.out.println(prop.getProperty("url"));  
        /* 
         * 總結:不能使用絕對地址,而只能只用相對地址 
         * 且不管加不加/的相對地址,都是相對於類路徑的相對地址 
         *  
         */  
    }  
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        doGet(request, response);  
    }  
  
}

3.3、Class獲取資源

  Class獲取資源主要是用作自己寫的配置文件,用來讀取內容

  用法:clazz.getResourceAsStream("路徑")。參數中的路徑可以以“/”開頭,也可以不以“/”開頭。其中帶“/”的表示相對於當前類的路徑,不以“/”開頭表示相對於當前class所在目錄的路徑

  Class讀取資源不能是絕對路徑,只能是相對路徑,又分為以/開頭或者是不以/開頭 。

public class ClassServlet extends HttpServlet {  
  
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        /* 
         * 1.以/開頭的相對路徑 
         *      此時的/代表類路徑,即:/javaee/WEB-INF/classes 
         */  
//      InputStream in = ClassServlet.class.getResourceAsStream("/cn/ccnu/classpath/b.properties");  
//      Properties porp = new Properties();  
//      porp.load(in);  
//      System.out.println(porp.getProperty("url"));  
        /* 
         * 2.不以/開頭的相對路徑 
         *      此時相對的是:類ClassServlet.class的路徑,即:\javaee\WEB-INF\classes\cn\ccnu\classpath 
         *      即:/javaee/WEB-INF/classes/cn/ccnu/classpath 
         */  
        InputStream in = ClassServlet.class.getResourceAsStream("b.properties");  
        Properties porp = new Properties();  
        porp.load(in);  
        System.out.println(porp.getProperty("url"));  
  
    }  
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        doGet(request, response);  
    }  
  
}  

 四、<url-pattern>路徑

   這里的路徑僅僅是指web.xml文件中的標簽內容。這個路徑是虛擬的路徑,只有相對路徑(相對於當前應用的路徑),但相對路徑的寫法可以是精確查詢和模糊查詢

   要么以“*”開關,要么為“/”開頭,當通常情況看下,我們都會以"/"開頭。

<!—精確查詢,是相對於當前應用-->
<url-pattern>/servlet/testPath</url-pattern>

<!—模糊查詢,表示匹配servlet目錄下的所有文件或請求。/*表示匹配所有-->
<url-pattern>/servlet/*</url-pattern>

<!—模糊查詢,表示匹配所有后綴名為do的文件或請求-->
<url-pattern>*.do</url-pattern>

五、總結

1)客戶端是帶“/”相對當前主機。

2)服務端(包括上述的服務端、url-pattern路徑和ServletContext路徑)帶不帶“/”都是相對當前應用(建議帶上)。

3)Class帶“/”是相對當前類路徑。不帶“/”是相對於當前位置。

4)ClassLoader無論帶不帶“/”都是當前類路徑(建議帶上)。   

 

喜歡就點個“推薦”哦!        


免責聲明!

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



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