【JavaWeb】web开发中的绝对路径和相对路径

一.基本概念

绝对路径:绝对路径就是你的网页资源 或者文件、目录在磁盘上真正的路径,(URL和物理路径)

  • 例如:C:\xyz\test.txt 代表了test.txt文件绝对路径http://www.sun.com/index.html也代表了一个
    URL绝对路径。

相对路径: 指目标相对于当前文件的路径。包含Web的相对路径(HTML中的相对目录)

  • 如:在Servlet中,"/"代表Web应用的根目录
  • 物理路径的相对表示。如:./代表当前目录,./代表上级目录。这种类似的表示,也是属于相对路径。

相对路径语法

  • ./:代表文件所在的目录(可以省略不写)

  • ../:代表文件所在的父级目录

  • ../../:代表文件所在的父级目录的父级目录

  • / :代表文件所在的根目录


值得注意的是,(/ :代表文件所在的根目录)其实可以理解成项目内部的绝对路径
在这里插入图片描述

html中的相对路径

图1所示目录结构为例,如果要在test.html中引入css1.css、css2.css文件,可以有以下写法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <!--相对路径获取: 获取当前文件同级目录下的 css1、css2文件-->
    <link href="css1/home/css1.css">
    <link href="css2/css2.css">

    <!--相对路径获取: 获取当前文件同级目录下的 css1.css2文件,等同于第一种方式-->
    <link href="./css1/home/css1.css">
    <link href="./css2/css2.css">

    <!--相对路径获取: 根据资源目录跟目录 下的 /html xxx 下的 css1、css2文件-->
    <link href="/html/css1/home/css1.css">
    <link href="/html/css2/css2.css">

    <!--相对路径获取: 获取当前文件父级目录html下的 css1.css2文件-->
    <link href="../html/css1/home/css1.css">
    <link href="../html/css2/css2.css">
</head>
<body>
<h1>test</h1>
</body>
</html>

在这里插入图片描述

html中的绝对路径
绝对路径是指完整的网址,假设图一中项目的网站ip为 http://localhost:8080,那么css1、css2的绝对路径应该是

http://localhost:8080/html/css1/home/css1.css
http://localhost:8080/html/css2/css2.css

二.Java中路径的使用

3.1./ 和 .符号

File file = new File("/");
System.out.println("/ 代表的绝对路径为:" + file.getAbsolutePath());

File file1 = new File(".");
System.out.println(". 代表的绝对路径为" + file1.getAbsolutePath());

执行结果

/ 代表的绝对路径为:D:
. 代表的绝对路径为D:\eclipse-workspace\SrcTest.

3.2.Java读取文件的三种方式

1.new File();

		//当前项目位置 E:\04_resource_study\springboot_demo

        //1.获取当前文件所在路径=>E:\04_resource_study\springboot_demo
        File file0 = new File("");
        //2.当前文件所在路径=>E:\04_resource_study\springboot_demo\.
        File file1 = new File(".");
        //3.根路径=>E:\
        File file2 = new File("/");

        //========使用 ""
        //4.表示""+src/test.txt,也就是当前目录所在路径下的src/test.txt   =>E:\04_resource_study\springboot_demo\src\test.txt
        File file3 = new File("src/test.txt");
        //5.表示""+test3.txt,也就是当前目录所在路径下的src/test.txt => E:\04_resource_study\springboot_demo\test3.txt
        File file4 = new File("test3.txt");

        //========使用 "."
        //5.表示当前所在目录+src/test.txt,   =>E:\04_resource_study\springboot_demo\.\src\test.txt
        File file5 = new File("./src/test.txt");
        //6.表示当前所在目录+test3.txt => E:\04_resource_study\springboot_demo\.\test3.txt
        File file6 = new File("./test3.txt");

        //========使用 "/"
        //7.表示根目录 /test.txt =>E:\src\test.txt
        File file7 = new File("/src/test.txt");
        //8.表示""+test3.txt => E:\test3.txt
        File file8 = new File("/test3.txt");

        System.out.println("--------------");
        System.out.println(file0.getAbsoluteFile());
        System.out.println(file1.getAbsoluteFile());
        System.out.println(file2.getAbsoluteFile());
        System.out.println("--------------");
        System.out.println(file3.getAbsoluteFile());
        System.out.println(file4.getAbsoluteFile());
        System.out.println("--------------");
        System.out.println(file5.getAbsoluteFile());
        System.out.println(file6.getAbsoluteFile());
        System.out.println("--------------");
        System.out.println(file7.getAbsoluteFile());
        System.out.println(file8.getAbsoluteFile());

在这里插入图片描述

在这种方法里面,"" 代表的是Java项目的根目录,“/” 代表磁盘根目录


2.getResource读取classpath的下的文件

    public static void main(String[] args) {
    
    
        //当前项目路径 E:\04_resource_study\springboot_demo
        //classpath路径是java项目编译后的路径,一般在war包或者java包里面名字为classes
        //当前类位于 E:\04_resource_study\springboot_demo\target\classes\com\ws\PathTest.class

        //获取当前文件在classpath下面的路径=>E:\04_resource_study\springboot_demo\target\classes\com\ws
        File file1 = new File(PathTest.class.getResource("").getFile());
        System.out.println(file1.getAbsoluteFile());
        System.out.println("--------------");

        //获取当前文件在classpath下面的路径=>E:\04_resource_study\springboot_demo\target\classes\com\ws
        File file2 = new File(PathTest.class.getResource(".").getFile());
        System.out.println(file2.getAbsoluteFile());
        System.out.println("--------------");

        //获取classpath的根路径=>E:\04_resource_study\springboot_demo\target\classes
        File file3 = new File(PathTest.class.getResource("/").getFile());
        System.out.println(file3.getAbsoluteFile());
        System.out.println("--------------");

        //获取classpath下面与当前class文件同级的的test.txt文件=>E:\04_resource_study\springboot_demo\target\classes\com\ws\test.txt
        File file4 = new File(PathTest.class.getResource("test.txt").getFile());
        System.out.println(file4.getAbsoluteFile());
        System.out.println("--------------");

        //获取classpath下面与的当前class文件同级的的test.txt文件=>E:\04_resource_study\springboot_demo\target\classes\com\ws\test.txt
        File file5 = new File(PathTest.class.getResource("./test.txt").getFile());
        System.out.println(file5.getAbsoluteFile());
        System.out.println("--------------");

        //获取classpath下面的test.txt文件=>E:\04_resource_study\springboot_demo\target\classes\test.txt
        File file6 = new File(PathTest.class.getResource("/test.txt").getFile());
        System.out.println(file6.getAbsoluteFile());
        System.out.println("--------------");
    }

如果想获取文件的字节流可以 调用class的getResourceAsStream()

执行结果
在这里插入图片描述
“/”代表的是classpath的根目录,因此要获取classpath下面的文件必须以 "/"开头 ,否则只会获取与当前class同级的文件


3. 使用线程的类加载器读取classpath下的文件

    public static void main(String[] args) {
    
    
        //当前项目路径 E:\04_resource_study\springboot_demo
        //classpath路径是java项目编译后的路径,一般在war包或者java包里面名字为classes
        //当前类位于 E:\04_resource_study\springboot_demo\target\classes\com\ws\PathTest.class

        //获取classpath根路径=>E:\04_resource_study\springboot_demo\target\classes
        File file1 = new File(Thread.currentThread().getContextClassLoader().getResource("").getFile());
        System.out.println(file1.getAbsoluteFile());
        System.out.println("--------------");

        //获取classpath根路径=>E:\04_resource_study\springboot_demo\target\classes
        File file2 = new File(Thread.currentThread().getContextClassLoader().getResource(".").getFile());
        System.out.println(file2.getAbsoluteFile());
        System.out.println("--------------");



        //获取classpath下面与当前class文件同级的的test.txt文件=>E:\04_resource_study\springboot_demo\target\classes\com\ws\test.txt
        File file4 = new File(Thread.currentThread().getContextClassLoader().getResource("test.txt").getFile());
        System.out.println(file4.getAbsoluteFile());
        System.out.println("--------------");

        //获取classpath下面与的当前class文件同级的的test.txt文件=>E:\04_resource_study\springboot_demo\target\classes\com\ws\test.txt
        File file5 = new File(Thread.currentThread().getContextClassLoader().getResource("./test.txt").getFile());
        System.out.println(file5.getAbsoluteFile());
        System.out.println("--------------");
    }

和第二种方式一样都是用于classpath下面的文件,不同的是可以直接从classpath下面获取文件, 不需要加 “/” 号。

  • 在上面的代码中可以看出,"" 和 . 都是可以表示classpath的根目录

执行结果
在这里插入图片描述

三.JavaWeb中的绝对、相对路径

5.1.概念

1.在JavaWeb中什么叫“绝对路径”:
相对于当前WEB应用的根路径的路径,即任何的路径都必须带上contextPath

http://localhost:8081/contextPath(当前WEB应用的上下文路径)/shopcart/submit.jsp=>正确
http://localhost:8081/a.jsp=>吃错误  

2.JavaWeb开发中 / 到底代表什么?

若/需交由Servlet容器来处理 ,称为 “WEB应用的根路径”:http://localhost:8081/contextPath/: `

  • 请求转发时:

    	request.getRequestDispatcher("/path/b.jsp").forward(request,response);
    
  • web.xml文件中映射Servlet访问路径:

    <servlet>
      	<servlet-name>Step2Servlet</servlet-name>
      	<servlet-class>Step2Servlet</servlet-class>
     </servlet>
    <servlet-mapping>
      	<servlet-name>Step2Servlet</servlet-name>
      	<url-pattern>/Step2Servlet</url-pattern>
    </servlet-mapping>
    

若/交由浏览器来处理,称为"WEB站点的根路径":http://localhost:8081/

  • 超链接:<a href="/TestServlet">To B Page</a>
    
    表达中的action:<from action="/login.jsp">
    
    做请求重定向的时候:response.sendRedirect("/a.jsp");
    

5.2.简述web根路径 / 的区别

web应用根路径/:

  • 当前web应用的上下文路径http://localhost:8080/projectName(当前web应用的上下文路径),可通过request.getContextPath()获取到
    • 如:一般的话是(web站点的根路径+项目名称)http://localhost:8080/springmvc

web站点根路径/:

  • 浏览器访问的工程名上一级的目录,比如:http://localhost:8080/projectName,则web站点的根目录就是projectName的上一级目录
    • 如:http://localhost:8080/

5.3.客户端和服务端关于根路径/的区别

  • 对于服务端来说,“/” 代表着的是web应用的根路径,即http://localhost:8080/projectName(当前web应用的上下文路径)

    应用场景如:请求转发web.xml中的路径url-pattern路径配置,都是由web服务器来调用执行的。

    • 请求转发:request.getRequestDispacter("/path/a.jsp").forward(request,response):=>则物理地址:http://localhost:8080/projectName/path/a.jsp
    • web.xml里面的<servlet-mapping><url-pattern><url-pattern>/a.jsp</url-pattern></servlet-mapping>映射的物理地址:http://localhost:8080/projectName/a.jsp

  • 对于由客户端来说 ,“/” 代表着的是web站点的根路径,即http://localhost:8080/

    应用场景如:a标签表单提交请求重定向

    • 超链接<a href="/testservlet"></a> => http://localhost:8080/testservlet
    • form表单的action<form action="/login.jsp"> => http://localhost:8080/login.jsp
    • 做请求重定向的时候response.sendRedirect("/a.jsp")=> http://localhost:8080/a.jsp
      • 重定向资源是在servlet代码中实现的,服务端是将要重定向的路径返回给浏览器,让浏览器重新请求,也归类为客户端请求,和浏览器在页面中发送请求的规律是一样的

举例说明前端如何使用 /

  • HTML中,“/”表示的是Web站点的根路径,案例中为http://localhost:8080/
  • 如果不加“/”,则是在当前页面的路径基础上,将请求的URI替换掉最后一个“/”后的资源名称。

如当前页面为: http://localhost:8080/projectName/html/test.html

  <img src="/projectName/images/pic.jpg"><br/>
	1.在HTML页面中的请求路径,斜杠“/”代表服务器站点的根路径,这里是 http://localhost:8080/,
    然后加上图片的URI地址(/projectName/images/pic.jpg),因此第一个的实际请求路径为:
    http://localhost:8080/projectName/images/pic.jpg

  <img src="/images/pic.jpg"><br/>
	2.第二个img标签的实际请求路径为:    http://localhost:8080/images/pic.jpg
    因此第一个图片可以正常显示,第二个路径是错误的(404)。

  <img src="images/pic.jpg"><br/>  
    3.如果路径前不加“/”,在浏览器会在当前页面(http://localhost:8080/projectName/html/test.html)的路径基础上,将请求的URI替换掉最后一个“/”后的资源名称(test.html)。
    则第三个img标签的src的实际请求路径为:
    http://localhost:8080/projectName/html/iamge/images.jpg 这个图片都不能正确显示(404)。

结果如下图所示,只有第一个图片请求成功

在这里插入图片描述

5.3.在jsp、servlet中 关于路径的使用

项目testProject
在这里插入图片描述

5.3.1.jsp页面到jsp页面

用链接进行跳转

相对路径的方式:  相对路径是根据当前页面的位置去定位目标的位置

<!--a.jsp=>b.jsp-->
<a href="b.jsp">转向b</a>

<!--a.jsp=>c.jsp-->
<a href="jsp/c.jsp">转向c</a>

<!--c.jsp=>a.jsp-->
<a href="../a.jsp">转向a</a>

绝对路径的方式:

<!--a.jsp=>b.jsp-->
<a hre="${pageContext.request.contextPath}/b.jsp">绝对转向b</a>

<!--a.jsp向c.jsp-->
<a hre="${pageContext.request.contextPath}/jsp/c.jsp">绝对转向c</a>

<!--c.jsp向a.jsp-->
<a hre="${pageContext.request.contextPath}/a.jsp">绝对转向a</a>

${pageContext.request.contextPath}的值:/testProject 其中“/”表示的是Web应用的根目录

  • 例如:Tomcat的webapps目录。所以后面拼接上jsp页面在项目中的路径就可以被浏览器访问到了,这就是绝对路径。

5.3.2.jsp页面到servlet

实际上和jsp到jsp一样,只是把jsp文件名xxx.jsp换成xxx/yyy这样的url而已

相对路径的方式

<!--a.jsp=>TestServlet-->
<a href="servlet/TestServlet">转向TestServlet</a>
<!--c.jsp=>TestServlet-->
<a href="../servlet/TestServlet">转向TestServlet</a>

绝对路径的方式:


<!--a.jsp=>TestServlet-->
 <a href="${pageContext.request.contextPath}/servlet/TestServlet">转向TestServlet</a>
<!--c.jsp=>TestServlet-->
<a href="${pageContext.request.contextPath}/servletTestServlet">转向TestServlet</a>

5.3.3.servlet发出的跳转(转发、重定向)

假设现在在TestServelt中 请求路径为http://localhost:8080/testProject/servlet/testServlet


请求转发到a.jsp :

request.getRequestDispatcher("../a.jsp").forword(request,response); 

../相对于退出一级(servlet这一级),回到 http://localhost:8080/testProject这里 ,拼接上a.jsp即得到正确路径url=http://localhost:8080/testProject/a.jsp,这是用的相对路径.

request.getRequestDispatcher("/a.jsp").forword(request,response);

这也可以实现正确跳转,因为这里的"/"表示web应用根路径http://localhost:8080/testProject


请求转发到Testservlet2:

request.getRequestDispatcher("testServlet2").forward(request,response);  

TestServlet和TestServlet2在同一层级,这里用的是相对路径

request.getRequestDispatcher("/servlet/testServlet2").forward(request,response);

这里就是绝对路径了,"/”表示web应用根路径


重定向到a.jsp

// request.getContextPath() 获取项目根路径  /testProject
response.sendRedirect(request.getContextPath() + "/a.jsp");//正确
response.sendRedirect("/a.jsp");

而这种写法是错误的 地址栏可见url=http://localhost:8080/a.jsp 因为这里的"/"表示的是web站点根目录,即:http://localhost:8080


转发与重定向

  1. 转发(forward)是以web应用根路径为基准的,可以跳转到同应用下任意有效资源页面
  2. WEB-INF只能被服务器端访问,不能被客户端访问,所以只能使用转发
  3. 重定向(sendRedirect)是服务器向客户端响应的资源名称,由客户端重新向服务器端请求。
  4. 重定向可以跨web应用

四.拓展

4.1.getContextPath、getServletPath、getRequestURI的区别

假定你的web应用名称为userCenter, 请求路径= http://localhost:8080/userCenter/main/list.jsp

使用一下方法返回

//返回当前请求所使用的协议。 一般的应用返回 "http",对于ssl则返回"https"
System.out.println(request.getScheme());//=>http
//返回服务器名字,如果是在本地的话就是localhost
System.out.println(request.getServerName());//=>localhost
//获得服务器的端口号
System.out.println(request.getServerPort());//=>8080
//获取请求的类型get、post、put等类型
System.out.println(request.getmethod());//=>GET
//获得客户端的ip地址
System.out.println(request.getRemoteAddr());//=>0:0:0:0:0:0:0:1

//返回项目根路径的名字(其实也就是项目名);
System.out.println(request.getContextPath());//=>/userCenter
//返回不包括项目根路径名称的请求路径
System.out.println(request.getServletPath()); //=>/main/list.jsp  
//返回的包括项目根路径到当前请求的请求路径
System.out.println(request.getRequestURI()); //=>/userCenter/main/list.jsp  
//返回的整个URL的路径请求(意思就是返回的浏览器地址栏的整个地址)
System.out.println(request.getRequestURL());//=>http://localhost:8080/userCenter/main/list.jsp  
//是返回的文件所在的绝对路径。相对于当前计算机的真实路径
System.out.println(request.getRealPath("/"));//返回 D:\Tomcat8\webapps\userCenter\test 

4.2.ServletContext的使用

ServletContext的getRealPath方法可以获取项目下任何位置资源的路径

  • 该方法都是从项目根路径(即站点+项目名称)下查找参数传递的资源路径,不论参数前是否有斜杠。
	//假设当前项目名为: projectName
    
    String path1 = getServletContext().getRealPath("/");
    System.out.println(path1);
    //  D:\tomcat8\webapps\projectName\
    
    String path2 = getServletContext().getRealPath("");
    System.out.println(path2);
    //  D:\tomcat8\webapps\projectName

    String path3 = getServletContext().getRealPath("projectName/iamge/pic.jpg");
    System.out.println(path3);
    //  D:\tomcat8\webapps\projectName\projectName\iamge\pic.jpg
    
    String path4 = getServletContext().getRealPath("/iamge/pic.jpg");
    System.out.println(path4);
    //  D:\tomcat8\webapps\projectName\iamge\pic.jpg
    
    String path5 = getServletContext().getRealPath("iamge/pic.jpg");
    System.out.println(path5);
    //  D:\tomcat8\webapps\projectName\iamge\pic.jpg
    
    String path6 = getServletContext().getRealPath("/pic.jpg");
    System.out.println(path6);
    //  D:\tomcat8\webapps\projectName\pic.jpg


在实际开发中,可以使用相对路径的时候,不要使用绝对路径.使用绝对路径的时候,尽量虚拟项目路径使用getContextPath()方法动态获取

猜你喜欢

转载自blog.csdn.net/qq877728715/article/details/103857500
今日推荐