判断路径前有没有 /
如果有 /
在浏览器被解析,那么会被解析为http://域名:port/
在服务器被解析,那么会被解析为http://域名:port/项目名[Application context]/
如果没有/
在浏览器被解析,那么会以相对路径来处理,及上一个界面的http://域名:port/项目名[Application context]/
在服务器被解析,如果是请求转发,那么由服务器来解析,服务器会默认前面有/
,解析为http://域名:port/项目名[Application context]/
。如果是请求重定向,那么由浏览器来解析,浏览器会以相对路径来处理。
判断路径后有没有/
如果有/
,会被当做路径来处理
如果没有/
,会被当做资源来处理
相对路径
- 说明:使用相对路径来解决,一个非常重要的规则:页面所有的相对路径,在默认情况下,都会参考当前浏览器地址栏的路径
http://ip:port/工程名/
+资源
来进行跳转。(说白了浏览器会帮你把http://ip:port/工程名/
补上,不用自己写) - 注意: 使用相对路径,一定要保证 访问两个资源的url都是
http://ip:port/项目名/资源名
,也就是说资源名前http://ip:port/工程名/
必须是一样,才能直接在action
中写上资源名
- 如果静态资源中要调用servlet,并且静态资源和servlet的相对路径一样,可以直接
<form action="servlet04"
>,如果相对路径不一样,就不能直接在action后面接servlet04
一般servlet路径都是http://localhost:8080/项目名[Application context]/servlet名称
)<在web.xml配置绝对路径>
静态资源如果在web目录下,访问路径http://localhost:8080/项目名[Application context]/静态资源名
静态资源如果在web目录下的子目录下,访问路径http://localhost:8080/项目名[Application context]/子目录名称/.../静态资源名
<!--
如果这个静态文件的访问路径为http://localhost:8080/webpath/login.html
那么action="servlet04" => http://localhost:8080/webpath/servlet04
-->
<form action="servlet04" method="post">
用户名: <input type="text"></br>
<input type="submit" value="提交"/>
</form>
相对路径带来的问题
- 两个资源不在同一目录下,但是其中一个资源又需要跳转(或者其他操作)到另一个资源上,这时,如果使用相对路径就会很麻烦,使用绝对路径又会很累赘
base标签
- base标签是HTML语言中的基准网址标记,它是一个单标签,位于网页头部文件的head标签内
- 一个页面最多只能使用一个base元素,用来提供一个指定的默认目标,是一种表达路径和连接网址的标记。
- 常见的url路径形式分别有相对路径与绝对路径,如果base标签指定了目标,浏览器将通过这个目标来解析当前文档中的所有相对路径,包括的标签有(a、img、link、form)
- 也就是说,浏览器解析时会在路径前加上base给的目标,而页面中的相对路径也都转换成了绝对路径。使用了base标签就应带上href属性和target属性
静态资源都是由浏览器来解析,因此在<base href="/项目名[Application context]/">
标签中,第一个/
会被解析成http://localhost:8080/
(浏览器知道资源是从哪来的,自然会解析成这个),而后面的项目名一般写为application context
<!--<base href="http://localhost:8080/webpath/">-->
<!--上面的写法可以简化一下-->
<!--
1. base标签是哪个在解析?=>浏览器
2.浏览器在解析第一个 / 时候,会解析成http://localhost:8080/
3.浏览器href="/webpath/" =解析=> href="http://localhost:8080/webpath/"
4.浏览器<a href="a.html">返回a. html~</a>,参考 base =>最后
href="http://localhost:8080/webpath/a.html"
5. href="/application context/" 里面的内容一般设置成application context
-->
<base href="/webpath/">
</head>
<body>
<h1>这是/d1/d2/b.html</h1>
<!--
1. 返回a.html =>使用前面的相对路径http://localhost:8080/webpath/d1/d2/
2. ../../a.html => http://localhost:8080/webpath/a.html
3. 相对路径会让这个项目相互调用的关系变得复杂
4. 使用base标签搞定
-->
<a href="a.html">返回a.html~</a>
</body>
在静态资源中获得其他资源的四种方式
项目名[application context]:webpath
下面这个静态资源路径:http://localhost:8080/webpath/login.html
要跳转的资源:http://localhost:8080/webpath/views/user/user.html
<head>
<meta charset="UTF-8">
<title>Title</title>
<base href="/webpath/views/user/">
</head>
<body>
<!--
1. 绝对路径 action="http://localhost:8080/webpath/views/user/user.html"
2. 相对路径 views/user/user.html
3. 使用base标签 user.html
4. action="/webpath/views/user/user.html"
浏览器对第一个 / 进行解析 为http://localhost:8080/ + webpath/views/user/user.html
-->
<form action="views/user/user.html" method="post">
服务器请求转发资源
服务器转发中第一个/
会被解析成http://localhost:8080/项目名[application context]/
,其实不加,也会默认有一个,但建议加上
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("servlet04被调用了...");
//使用转发
//注意第一个/被服务器解析成/webpath/
//因为请求转发是发生服务器端,所以通过/webpath/views/user/user.html
//可以定位该资源
request.getRequestDispatcher("/views/user/user.html").forward(request, response);
//不加 / 也行,会默认前面有一个 / 建议加上
request.getRequestDispatcher("views/user/user.html").forward(request, response);
}
服务器请求重定向资源
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 这里如何通过重定向来定位 /views/user/user.html/
* 分析出重定向是发生在 浏览器
* 1. "views/user/user.html" 相对路径
* 2. "http://localhost:8080/webpath/views/user/user.html" 绝对路径
* 3. "/webpath/views/user/user.html" 第一个 / 会被浏览器解析为http://localhost:8080/
* 4. contextPath + "/view/user/user.html"
* 推荐第四种写法
*/
System.out.println("调用了Servlet05的doPost()...");
// response.sendRedirect("/webpath/views/user/user.html");
// response.sendRedirect("views/user/user.html");
// response.sendRedirect("http://localhost:8080/webpath/views/user/user.html");
String contextPath = getServletContext().getContextPath();
response.sendRedirect(contextPath + "/views/user/user.html");
}
web路径事项与细节
- Web工程的相对路径和绝对路径
● 相对路径是:
●.
表示当前目录
●..
表示上一级目录
● 资源名表示当前目录/资源名
● 绝对路径: http:// ip:port/工程路径/资源路径 - 在实际开发中,路径都使用绝对路径,而不是相对路径
- 在 web中
/
斜杠如果被浏览器解析,得到的地址是:http://ip[域名]:port/
比如:<a href="/"">斜杠</a>
- 在web中
/
斜杠如果被服务器解析,得到的地址是:http://ip[域名]:port/工程路径/
- 在javaWeb中路径最后带/和不带/含义不同,一定要小心,
比如<a href="/a/servlet03">网址</a>
: servlet03表示资源<a href="/a/servlet03/">网址</a>
: servlet03表示路径 - 特别说明:重定向
response.sendRediect("/");
这条语句虽然是在服务器执行的,但是,服务器是把斜杠(发送给浏览器解析。因此得到地址http://ip[域名]:port/
小结:在编写资源路径时:,考虑这么几点
- 这个路径前面有没有 /
- 这个路径在哪里被解析【服务器还是浏览器],如果前面有/,并且是在浏览器被解析的被解析成
http://ip:port/
,如果在服务器端被解析,被解析成/工程路径/
- 如果这个路径,前面没有 / ,并且在浏览器被解析,则以浏览器当前的地址栏去掉资源部分,作为一个相对路径
- 这个路径,最后有没有/,如果最后有 / 表示路径,如果没有 / 表示资源
工程路径问题
解决方案:相对路径
注意: 使用相对路径,一定要保证 访问两个资源的url都是http://ip:port/项目名/资源名
,也就是说资源名前http://ip:port/项目名/
必须是一样的
<body>
<!-- 1.可以看到,我们原来的访问一个web资源的路径非常的麻烦
2.目前我们访问的是ok的资源
3.我们可以使用相对路径来解决
4. http://localhost:8080/webpath/ok => ok
5.如果你action="ok" 等价 http://localhost:8080/webpath/ok
-->
<h1>注册用户</h1>
<form action="ok" method="post">
u: <input type="text" name="username"/><br><br>
<input type="submit" value="注册用户"/>
</form>
</body>
相对路径带来的问题
访问a.html
文件路径:http://localhost:8080/webpath/d1/d2/a.html
访问b.css
文件路径:http://localhost:8080/webpath/css/mycss/my.css
如果a.html要引入b.css文件,如果使用相对路径,就会非常麻烦../../css/my.css
希望有一种方式可以通过 ip:port/项目名 + 资源名 的方式来定位资源
base标签
a.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--相对路径
1. href="d1/d2/b.html" 等价于 http://localhost:8080/项目名/d1/d2/b.html
-->
<h1>这是a.html</h1>
<a href="d1/d2/b.html">跳转到/d1/d2/b.html</a><br/><br/>
<a href="servlet03">转发到/d1/d2/b.html</a></body>
</html>
</body>
</html>
/d1/d2/b.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--
1.下面老师写的base href="http://localhost:8080/webpath/
2.表示的含义就是当前这个页面的访问所有资源都是以http://localhost:8080/webpath/参照
-->
<!--<base href="http://localhost:8080/webpath/">-->
<!--上面的写法可以简化一下-->
<!--
1. base标签是哪个在解析?=>浏览器
2.浏览器在解析第一个 / 时候,会解析成http://localhost:8080/
3.浏览器href="/webpath/" =解析=> href="http://localhost:8080/webpath/"
4.浏览器<a href="a.html">返回a. html~</a>,参考 base =>最后
href="http://localhost:8080/webpath/a.html"
5. href="/application context/" 里面的内容一般设置成application context
-->
<base href="/webpath/">
</head>
<body>
<h1>这是/d1/d2/b.html</h1>
<!--
1. 返回a..html =>使用前面的相对路径http:/ /localhost:8080/webpath/d1/d2/
2. ../../a.html => http://localhost:8080/webpath/a.html
3. 相对路径会让这个项目相互调用的关系变得复杂
4. 使用base标签搞定
-->
<a href="a.html">返回a.html~</a>
</body>
</html>
服务器请求转发资源
a.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--相对路径
1. href="d1/d2/b.html" 等价于 http://localhost:8080/项目名/d1/d2/b.html
-->
<h1>这是a.html</h1>
<a href="d1/d2/b.html">跳转到/d1/d2/b.html</a><br/><br/>
<a href="servlet03">转发到/d1/d2/b.html</a></body>
</html>
</body>
</html>
servlet03
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 珀筱
*/
public class Servlet03 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1、在服务器端解析第一个 / 时,会被解析成http://ip:port/项目名[application context]
//2."/d1/d2/b.html" =>被解析http://ip:port/项目名/d1/d2/b.html
//3. / 本身解析在服务端,因此 / 被解析成/项目名[application context]也是没问题的,与上面那种说法大同小异
System.out.println("servlet03转发...");
request.getRequestDispatcher("/d1/d2/b.html").forward(request, response);
//3.在服务器进行转发时,没有/就按照默认的方式参考定位http://ip:port项目
//老师建议,仍然使用上面的
//request.getRequestDispatcher("d1/d2/b.html").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
web路径事项与细节
服务器重定向资源
package com.study.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 珀筱
*/
public class Servlet05 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 这里如何通过重定向来定位 /views/user/user.html/
* 分析出重定向是发生在 浏览器
* 1. "views/user/user.html" 相对路径
* 2. "http://localhost:8080/webpath/views/user/user.html" 绝对路径
* 3. "/webpath/views/user/user.html" 第一个 / 会被浏览器解析为http://localhost:8080/
* 4. contextPath + "/view/user/user.html"
* 推荐第四种写法
*/
System.out.println("调用了Servlet05的doPost()...");
// response.sendRedirect("/webpath/views/user/user.html");
// response.sendRedirect("views/user/user.html");
// response.sendRedirect("views/user/user.html");
// response.sendRedirect("http://localhost:8080/webpath/views/user/user.html");
String contextPath = getServletContext().getContextPath();
response.sendRedirect(contextPath + "/views/user/user.html");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}