文章目录
一.基本概念
绝对路径:绝对路径就是你的网页资源 或者文件、目录在磁盘上真正的路径,(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/testservletform表单的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
转发与重定向
- 转发(forward)是以web应用根路径为基准的,可以跳转到
同应用下任意有效资源页面
- WEB-INF只能被
服务器端
访问,不能被客户端访问,所以只能使用转发
- 重定向(sendRedirect)是服务器向客户端响应的资源名称,由客户端重新向服务器端请求。
- 重定向可以
跨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()方法动态获取