Web工程路径专题

一、工程路径问题

1. 问题引出

问题:web/index.html

新建工程:new project->选Java->一直下一步到修改项目和路径即可,修改名字创建项目

add framework选WebApplication4.0,添加Servlet-api,部署Tomcat,不再赘述

添加index.html页面

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>base 标签</title>
</head>
<body>
    <h1>注册用户~</h1>
    <form action="http://localhost:8080/webpath/ok" method="post">
        u: <input type="text" name="username"/><br><br>
        <input type="submit" value="注册用户"/>
    </form>
    <h1>讨论区</h1>
    <form action="http://localhost:8080/webpath/ok" method="post">
        讨论内容: <textarea cols="50" rows="5"></textarea><br><br>
        <input type="submit" value="发布讨论"/>
    </form>
    <h1>回复区</h1>
    <form action="http://localhost:8080/webpath/ok" method="post">
        回复内容: <textarea cols="50" rows="5"></textarea><br><br>
        <input type="submit" value="回复"/>
    </form>
</body>
</html>

可以看到以前路径写的是全路径,比较麻烦

我们可以采用相对路径

2. 相对路径

使用相对路径来解决,一个非常重要的规则:页面所有的相对路径,在默认情况下,都会参考当前浏览器地址栏的路径http://ip:port/工程名/ + 资源来进行跳转,我们可以直接这样

二、base标签

1. base标签介绍

如果需要指定页面相对路径参考的的路径,可以使用base标签来指定

base标签是HTML语言中的基准网址标记,它是一个单标签,位于网页头部文件的head标签内

一个页面最多只能使用一个base元素,用来提供一个指定的默认目标,是一种表达路径和连接网址的标记

常见的url路径形式分别有相对路径与绝对路径,如果base标签指定了目标,浏览器将通过这个目标来解析当前文档中的所有相对路径,包括的标签有(a、img、link、form)

也就是说,浏览器解析时会在路径前加上base给的目标,而页面中的相对路径也都转换成了绝对路径。使用了base标签就应带上href属性和target属性

2. 实例-静态页面跳转

需求:演示base标签的使用,说明:先演示和html相关的路径跳转,再演示和Servlet路径转发

在web目录下创建a.html文件

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>a.html</title>
</head>
<body>
    <h1>这是 a.html</h1>
    <a href="b1/b2/b.html">跳转到/b1/b2/b.html</a>
    <br/><br/>
    <a href="servlet03">转发到/b1/b2/b.html</a>
</body>
</html>

在web下创建b1目录,b1目录下创建b2目录,b2下创建b.html文件

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>b.html</title>
    <!-- 解读
    1. 如果没有<base href="http://localhost:10000/hspedu_servlet/">
    2. 当点击 返回 a.html 超链接,将会以当前浏览器的地址为路径来确定 路径
    3. 如果增加了<base href="http://localhost:10000/hspedu_servlet/">
    4. 将以 base 指定的 href 的地址为路径,来确定 超链接的路径
    -->
    <!--<base href="http://localhost:10000/hspedu_servlet/">-->
    <!--简写形式-->
</head>
<body>
    <h1>这是/b1/b2/b.html</h1>
    <a>返回 a.html~</a>
</body>
</html>

上面的b1/b2/b.html等价于http://localhost:8080/项目名/b1/b2/b.html

如果想再访问回a.html,第一种方式可以采用这样基础的base标签

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>b.html</title>
    <!-- 解读
    1. 如果没有<base href="http://localhost:10000/hspedu_servlet/">
    2. 当点击 返回 a.html 超链接,将会以当前浏览器的地址为路径来确定 路径
    3. 如果增加了<base href="http://localhost:10000/hspedu_servlet/">
    4. 将以 base 指定的 href 的地址为路径,来确定 超链接的路径
    -->
    <!--<base href="http://localhost:10000/hspedu_servlet/">-->
    <!--简写形式-->
    <base href="http://localhost:8080/webpath/">
</head>
<body>
    <h1>这是/b1/b2/b.html</h1>
    <a href="a.html">返回 a.html~</a>
</body>
</html>

注意:上面http://localhost:8080/webpath/的"/"必须要带上,带上是个路径,不带上http://localhost:8080/webpath就表示一种资源

当然上面也可以表示为如下方式,下面两个等价:

html 复制代码
<base href="http://localhost:8080/webpath/">
<base href="/webpath/">

因为base标签是浏览器在解析,浏览器在解析第一个"/"的时候,会将其解析成http://localhost:8080/

上面base标签已经将整个路径解析成路径了,如果<a href="/a.html">返回 a.html~</a>再在a.html前加上/a.html,就会再次将第一个"/"解析成项目的路径http://localhost:8080/

3. 实例-Servlet跳转

正常情况下不是直接从静态页面跳转的,而是使用Servlet跳转

需求:这里使用Servlet实现跳转

上面a.html里有这个a标签,href就等于http://localhost:8080/项目名/servlet03

html 复制代码
<a href="servlet03">转发到/b1/b2/b.html</a>

不能在前面带/,变成/servlet03,因为会变成http://localhost:8080/servlet03

java 复制代码
@WebServlet(name = "Servlet03", urlPatterns = "/servlet03")
public class Servlet03 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //在服务器端解析第一个/时,会被解析成http://localhost:8080/项目名
        //这里项目名是工程路径,因为转发是发生在服务端的,所以也可以理解"/"被解析成/项目
        System.out.println("Servlet3 doPost转发");
        request.getRequestDispatcher("/b1/b2/b.html").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

注意:在服务器端解析第一个/时,会被解析成http://localhost:8080/项目名 这里项目名是工程路径,因为转发是发生在服务端的,所以也可以理解"/"被解析成/项目

有的程序员会按照request.getRequestDispatcher("b1/b2/b.html").forward(request,response);方式去请求,也就是b1/b2/b.html前面不带斜杠,这样有时也是可以的,但是不建议 ,如果服务器进行转发时,前面没找到/,就会按照默认的http://localhost:8080/项目名方式去访问

前面的项目名其实就是自己配置的application context

三、WEB工程路径注意事项和细节

1. Web工程的相对路径和绝对路径

相对路径是:

在实际开发中,路径都使用绝对路径,而不是相对路径

在Web中"/"斜杠如果被浏览器解析,得到的地址是:http://ip[域名]:port/,比如: 斜杠

在Web中"/"斜杠如果被服务器解析,得到的地址是:http://ip[域名]:port/工程路径/,你也可以理解成/工程路径/

下面的几种情况就是如此:

  • <url-pattern>/servelturl</url-pattern>
  • servletContext.getRealPath("/"); ==> 是得到执行路径/工作路径,也就是out/artifacts/webpath/
  • servletContext.getContextPath();==>是相对路径,配置的application context,可以用在服务器渲染技术
  • request.getRequestDispatcher("/");

在JavaWeb中路径最后带/和不带/含义不同,一定要小心,比如网址</a>: servlet03表示资源

特别说明:重定向response.sendRediect("/");这条语句虽然是在服务器执行的,但是,服务器是把斜杠 / 发送给浏览器解析。因此得到地址:http://ip[域名]:port/

在编写资源路径时,考虑这么几点:

  • 这个路径前面有没有"/"

  • 这个路径在哪里被解析[服务器还是浏览器],如果前面有/,并且是在浏览器被解析的,被解析成http://ip:port/,如果在服务器端被解析,被解析成

    /工程路径/

  • 如果这个路径,前面没有/,并且在浏览器被解析,则以浏览器当前的地址栏去掉资源部分,作为一个相对路径,这个路径,最后有没有/,如果最后有/表示路径,如果没有/表示资源

2. Web工程路径优化

前面的base标签是可以被优化的,可以使用动态技术,如jsp、theamleaf,这里使用jsp:

java 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    动态获取到工程路径:<%=request.getContextPath()%>
  </body>
</html>

结果如下:

相关推荐
咖啡の猫33 分钟前
Shell脚本-for循环应用案例
前端·chrome
uzong2 小时前
面试官:Redis中的 16 库同时发送命令,服务端是串行执行还是并行执行
后端·面试·架构
百万蹄蹄向前冲3 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
追逐时光者3 小时前
.NET 使用 MethodTimer 进行运行耗时统计提升代码的整洁性与可维护性!
后端·.net
朝阳5813 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路4 小时前
GeoTools 读取影像元数据
前端
ssshooter4 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
你的人类朋友4 小时前
【Node.js】什么是Node.js
javascript·后端·node.js
Jerry5 小时前
Jetpack Compose 中的状态
前端
David爱编程5 小时前
面试必问!线程生命周期与状态转换详解
java·后端