本篇供个人学习使用,有问题欢迎讨论
访问路径问题
一、访问路径的组成
URL,统一资源定位符,用于定位资源的一种方式。通常的URL资源访问路径由两部分构成:资源路径与资源名称。资源名称指的是要访问资源的直接名称,如show.html,或与要访问资源存在映射关系的间接名称,如show.do。而资源路径,则是通过该路径则可以定位到指定的资源,即资源路径是指在URL资源访问路径中除了资源名称以外的其它部分。
根据以上规则,URI(统一资源标识符), 也可以分为资源路径与资源名称两部分。
一般情况下, 在URL或URI中,最后一个斜杠后的部分为资源名称,而其它部分则为资源路径。
根据 “资源路径是否可以独立完成资源准确定位” 的判别标准,可以将访问路径分为绝对路径与相对路径。
二、绝对路径
绝对路径,是指根据给出的访问路径可以准确定位到资源的路径。例如,你要告诉对方你现在的位置,你说:我现在在武汉黄鹤楼游客A入口处。这就是个绝对地址,听者根据你所述地址,可以准确的找到你。
而对于计算机中Web应用的绝对路径,则是指带访问协议的路径,即URL。例如下面的路径就是一个带有http访问协议的绝对路径。
http://127.0.0.1:8080/primary/index.jsp
三、相对路径
相对路径,是指仅根据访问路径无法准确定位资源的路径。相对路径必须要结合其参照路径才可组成可以准确定位资源的绝对路径。参照路径的不同,所形成的可以准确定位资源的绝对路径也是不同的。在进行资源访问时,必须要将相对路径转换为绝对路径才可完成资源的准确定位。它们的关系如下:
绝对路径 = 参照路径 + 相对路径
例如,你要告诉对方你现在的位置,你说:我在人民公园的正了门口。这就是个相对地址因为很多城市都有人民公园,每个人民公园也都有正门。当对方不知道你在哪个城市时,他是无法准确定位你的。当然,你只所以不说是哪个城市,是因为这里存在一个默认的参照路径:与听者在同一个城市。听者会将你所说的相对地址,自动转换为一个绝对地址:与听者在同一城市的人民公园正门门口。
在Web应用中,浏览器或服务器会自动为不同的相对路径添加不同的参照路径,将相对路径转换为绝对路径,以定位这个资源。作为程序员,必须要理解并掌握浏览器或服务器为相对路径添加参照路径的规则,这样才能在编程时更为准确地书写相对路径。
相对路径的写法有两种:一种是以斜杠开头的相对路径,一种是以路径名称开头的相对路径。根据相对路径是否以斜杠开头,且路径出现的文件的不同,其默认的参照路径是不同的。这是我们学习的重点,是路径问题中最容易出错的地方:确定相对路径的参照路径。
1、以斜杠开头的相对路径
以斜杠开头的相对路径,根据路径所在文件所处位置的不同,分为两种:前台路径与后台路径。
(1)前台路径
所谓前台路径是指,由浏览器解析执行的代码中所包含的路径。例如,html、 css、 js中的路径,及jsp文件中静态部分的路径(HTML 标签中的路径)。例如,html及jsp 文件中的<img src="”/>、<a href=""></a>、<form action=""></form>等标签中的路径;再如,css文件中的background:img(" “)等属性中的路径,js文件中的window.location.href=" "等属性中的路径,都属于前台路径。
前台路径的参照路径是Web服务器的根路径,即http://127.0.0.1:8080
将前台路径转换为绝对路径的工作,是由浏览器自动完成的。该路径的作用是要为用户提交对某种资源的请求,是要查找并定位服务器中的某资源。简单来说,前台路径的作用是 “查找” 。
(2)后台路径
所谓后台路径是指,由服务器解析执行的代码及文件中所包含的路径。例如, java 代码中的路径、jsp 文件动态部分(java 代码块)中的路径、xml等配置文件中的路径(配置文件是要被java代码解析后加载到内存的,其中的路径会出现在Java代码中)等。
后台路径的参照路径是Web应用的根路径。如http://127.0.0.1:8080/primary
将后台路径转换为绝对路径的工作,是由服务器自动完成的。该路径的作用是标识出该资源在服务器中的路径,以便客户端能够按照这个设定路径来查找相应资源。简单来说,后台路径的作用是 “标识” 。
(3)后台路径特例
对于后台路径的参照路径有一个特例:当代码中使用response的sendRedirec()方法进行重定向时,若其参照路径是以斜杠开头,则其参照路径不是web应用的根路径,而是web服务器的根路径。
例如,执行response.sendRedirect("/show.jsp");将会报404 错误。因为其参照路径是Tomcat的根,而非当前项目的根。所以若要使用重定向,就需要在路径上添加上项目名称:
response.sendRedirect(request.getContextPath + "/show.jsp");
为什么这里是特例?因为sendRedirect()方法可以重定向到其它应用,若不指定要跳转的应用,其将无法确定跳转方向。
2、以路径名称开头的相对路径
以路径名称开头的相对路径,无论是出现在前台页面,还是出现在后台Java代码或配置文件中,其参照路径都是当前访问路径的资源路径。即使是response 的sendRediret()方法的参数路径,若不以斜杠开头,其也属于“以路径名称开头的相对路径”类,参照路径为当前访问路径的资源路径。
3、总结
相对路径类型 | 参照路径 | 相对路径转为绝对路径的完成者 |
---|---|---|
前台路径 | 当前Web服务器的根路径,例如:http://localhost:8080 | 浏览器 |
后台路径 | 当前Web应用的根路径,例如:http://localhost:8080/primary | Web服务器 |
以路径名称开头的相对路径 | 当前访问路径的资源路径 | 浏览器 / Web服务器 |
四、前台路径问题举例
1、超链接前台路径举例分析
(1)该路径是一个前台路径。前台的参照路径是当前Web服务器的根路径,即
参照路径为:http://localhost:8080
绝对路径 = 参照路径 + 相对路径,那也就是说,浏览器会将这个路径自动转换为的绝对路径是:http://localhost:8080/images/mm.jpg
在Web服务器下是没有images目录的,所以这个相对路径是无法显示图片的
<img alt="mm" src="/images/mm.jpg">
(2)该路径是一个前台路径。前台的参照路径是当前Web服务器的根路径。即
参照路径为:http://localhost:8080
绝对路径 = 参照路径 + 相对路径,那也就是说,浏览器会将这个路径自动转换为的绝对路径是:http://localhost:8080/myWeb/images/mm.jpg
在Web服务器下有myWeb项目,而该项目下有images/mm.jpg资源,所以这个相对路径是可以正确显示图片的
<hr>
<img alt="mm" src="/myWeb/images/mm.jpg">
2、表单前台路径举例分析
(1)这是一个前台路径,前台路径的参数路径是当前Web服务器的根,即http://localhost:8080
绝对路径 = 参数路径 + 相对路径
即浏览器会自动将这个前台路径转换为绝对路径http://localhost:8080/one.do
在Web服务器的根目录中没有OneServlet这个东西,所以这个访问路径是无法访问到OneServlet的,会报404错误
<form action="/one.do" method="get">
用户名:<input type="text" name="username" /><br>
<input type="submit" value="登录">
</form>
(2)这是一个前台路径,前台路径的参数路径是当前Web服务器的根,即http://localhost:8080
绝对路径 = 参数路径 + 相对路径
即浏览器会自动将这个前台路径转换为绝对路径http://localhost:8080/one.do
在Web服务器的根目录中有OneServlet这个东西,所以这个访问路径是可以访问到OneServlet的。
<form action="/myWeb/one.do" method="get">
用户名:<input type="text" name="username" /><br>
<input type="submit" value="登录">
</form>
五、后台路径问题举例
1、配置文件后台路径举例分析
<servlet-mapping>
<servlet-name>TwoServlet</servlet-name>
<url-pattern>/two.do</url-pattern>
</servlet-mapping>
这是一个后台路径,后台路径的参照路径是当前Web应用的根,即http://localhost:8080/myWeb
绝对路径 = 参照路径 + 相对路径
将相对路径转换为绝对路径工作,是由Web服务器完成的,服务器会将这个相对路径转换为:
http://localhost:8080/myWeb/two.do
后台路径的绝对路径,其作用是 “标识” 。即客户端要想访问我这里定义的TwoServlet。那么,必须要提交上面的绝对路径。
客户端现在提交的请求为:http://localhost:8080/myWeb/two.do
。其与这里的绝对路径是相同的,所以这个请求是可以访问到TwoServlet的
2、Java文件后台路径举例分析
服务器会将这个相对路径转变为如下的绝对路径:http://localhost:8080/myWeb/two.do
这个绝对路径的意思是,若想访问我这里定义的TwoServlet,那你就必须提交如上形式的访问路径。即这里指定了TwoServlet这个资源的访问路径
<servlet-mapping>
<servlet-name>TwoServlet</servlet-name>
<url-pattern>/two.do</url-pattern>
</servlet-mapping>
这是一个后台路径,后台路径的参照路径是当前Web应用的根,即http://localhost:8080/myWeb
绝对路径 = 参照路径 + 相对路径
将这个相对路径转换为绝对路径的工作,是由Web服务器完成的。即服务器会将这个相对路径转换为:http://localhost:8080/myWeb/two.do
。服务器中对于TwoServlet这个资源指定的访问路径是:http://localhost:8080/myWeb/two.do
。请求路径与资源的 “标识” 路径是相同的,那么,这个请求是可以跳转成功的
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("This is OneServlet...");
request.getRequestDispatcher("/two.do").forward(request,response);
}
3、后台路径特例举例分析
注意,对于response的sendRedirect()方法完成的重定向,若其参数路径为 “以斜杠开头的相对路径”
这个后台路径是个特例。只所以其为特例,是由sendRedirect( )方法的本质决定的。这个方法不仅可以完成在当前项目中资源的跳转,还可以跳转到其它项目中的资源。所以这个后台路径的参照路径为 “当前Web服务器的根”。
(1)下面的写法无法完成跳转
response.sendRedirect("/two.do");
(2)下面的写法可以完成跳转,但这样写不太好,写死了
response.sendRedirect("/myWeb/two.do");
(3)下面的写法才是最好的写法,具有动态性
response.sendRedirect(request.getContextPath() + "/two.do");
六、以路径名称开头的相对路径举例
1、前台页面中以路径名称开头的相对路径举例
(1)超链接前台路径
这是一个 “以路径名称开头的相对路径” ,其参照路径是 “当前访问路径的资源路径” ,对于本例而言,就是:http://localhost:8080/myWeb
绝对路径 = 参照路径 + 相对路径
浏览器会自动将这个相对路径转换为绝对路径:http://localhost:8080/myWeb/images/mm.jpg
<img alt="mm" src="images/mm.jpg">
(2)表单前台路径
这是一个 “以路径名称开头的相对路径” ,其参照路径是 “当前访问路径的资源路径” ,对于本例而言,就是:http://localhost:8080/myWeb
绝对路径 = 参照路径 + 相对路径
浏览器会自动将这个相对路径转换为绝对路径:http://localhost:8080/myWeb/one.do
OneServlet在注册时被指定的路径为:http://localhost:8080/myWeb/one.do
。请求提交的路径与要求路径相同,所以这个相对路径可以完成跳转
<form action="one.do" method="get">
用户名:<input type="text" name="username" /><br>
<input type="submit" value="登录">
</form>
2、Java代码中以路径名称开头的相对路径举例
(1)请求转发
这是一个 “以路径名称开头的相对路径” ,其参照路径是 “当前访问路径的资源路径” ,对于本例而言,就是:http://localhost:8080/myWeb
绝对路径 = 参照路径 + 相对路径
服务器会自动将这个相对路径转换为绝对路径:http://localhost:8080/myWeb/two.do
request.getRequestDispatcher("two.do").forward(request,response);
(2)重定向
注意,对于respoqse的sendRedirect( )方法完成的重定向,若参数路径不以斜杠开头,其是满足之前的路径理论的。其不是特例。下面的相对路径是可以完成跳转的。
response.sendRedirect("two.do");
注意:若相对路径加上斜杠与不加斜杠,都可以完成跳转,那么,就要加上斜杠。因为加上斜杠后前面的资源路径名称是固定的。