Servlet路径问题(“/“到底代表什么)-“web应用程序的根目录“与“web站点的根目录“

news2024/11/26 2:23:14

JavaWeb——Servlet路径问题("/"到底代表什么)

JavaWeb——Servlet路径问题("/"到底代表什么)

在JavaWeb中,使用路径时出现了大量的"/“,而每次使用”“时都感觉其代表的含义是不同的,因此,本篇文章将汇总JavaWeb中的”"出现情况及其所代表的含义。

了解这些"/"含义之前,先来了解绝对路径与相对路径的概念。

提前说一下自己总结的规律:

若是**浏览器中请求服务器**,则此时绝对路径的"/“代表的是**服务器(Tomcat)的根目录**,而此时的相对路径代表的是**该项目的根目录**
   若在**服务器中请求服务器**,则此时绝对路径的”/"或相对路径代表的都是该项目的根目录
   而在服务器内部,可以这样理解,服务器在解析路径时,‘src’、'webapp’这些文件夹其实都被忽略了,也就是说,这两个目录下的文件可以认为是在同一目录(该项目的根目录)下
  一定要看使用的是什么路径,如果是相对路径,只需要看目标文件与当前文件之间的位置关系即可,而如果是绝对路径,才需要注意上面这几点要求。

1、"/"出现在请求重定向与请求转发中

有关请求转发与请求重定向的概念,这里不再赘述,请参考:请求转发与请求重定向。
在这里插入图片描述

由于请求转发是服务器内部行为,是在服务器中请求服务器,因此请求转发中的"/"表示该项目的根目录

由于请求重定向是浏览器行为,是在浏览器中请求服务器,因此请求重定向的"/"表示Tomcat服务器的根目录

先来看请求转发,此时dispatcher.jsp与request_form.jsp由于上面第三条的存在,都处于该项目的根目录,因此若使用绝对路径,可以再dispatcher.jsp中使用"/request_form.jsp"访问到request_form.jsp,若使用相对路径,由于dispatcher.jsp与request_form.jsp同在一个目录(项目根目录)下,因此也可以直接使用"request_form.jsp"访问到request_form.jsp。

	// 请求转发使用下面两种方式均可以访问到request_form.jsp
	// 使用绝对路径
	request.getRequestDispatcher("/request_form.jsp").forward(request,response);
	// 使用相对路径
	request.getRequestDispatcher("request_form.jsp").forward(request,response);

下面看一下请求重定向,若使用相对路径,由于dispatcher.jsp与request_form.jsp同在一个目录中,因此使用"request_form.jsp"就可以访问,但对于相对路径来说,此时的"/"代表Tomcat服务器的根目录,因此要想访问该项目根目录中的文件,需要加上该项目根目录路径(需要与tomcat中该项目的路径相同或使用request.getContextPath()),再加上该文件的路径。

	// 请求重定向使用下面两种方式均可以访问到request_form.jsp
	// 使用相对路径
	response.sendRedirect("request_form.jsp");
	// 使用绝对路径
	response.sendRedirect("/javaweb_jsp/request_form.jsp");
	response.sendRedirect(request.getContextPath()+"/request_form.jsp");

2、"/"出现在web.xml文件中(中的)

servlet的相对路径跳转是相对于servlet配置的xml路径(或servlet3.0注解路径),无论是使用配置文件的方式还是注解的方式,在描述绝对路径的时候就不要多说,此时不需要知道servlet到底在哪,而只需要知道目标文件在哪即可,若servlet和目标文件都在同一服务器中,就相当于是服务器内部请求(请求转发或重定向均可),若servlet和目标文件在不同服务器中,使用请求重定向即可。

若servlet与目标文件处于同一服务器中,并且是以相对路径来调用,无论是配置文件还是注解,只需要servlet的url-pattern(注解里也有)与目标文件的相对位置即可。举个栗子:
在这里插入图片描述

	// web.xml中的servlet配置
	 <servlet>
        <servlet-name>Dispatcher</servlet-name>
        <servlet-class>com.xiaoaxiao.test.Dispatcher</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Dispatcher</servlet-name>
        <url-pattern>/dis</url-pattern>
    </servlet-mapping>

	// Dispatcher(继承了HttpServlet)中的请求转发
	req.getRequestDispatcher("login.html").forward(req,resp);

解析一下这个例子,此时的servlet根据配置文件的url-pattern配置可以看出,该servlet的路径相当于是在"/dis",即当前项目的根目录下(起了个名字叫dis),而login.html也是处于当前项目的根目录,因此使用相对路径访问直接"login.html"即可。
  还是同样的结构图,将配置文件中的url-pattern修改为"/test/dis"

	// web.xml中的servlet配置
	 <servlet>
        <servlet-name>Dispatcher</servlet-name>
        <servlet-class>com.xiaoaxiao.test.Dispatcher</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Dispatcher</servlet-name>
        <!-- 修改了此配置-->
        <url-pattern>/test/dis</url-pattern>
    </servlet-mapping>

	// Dispatcher(继承了HttpServlet)中的请求转发
	req.getRequestDispatcher("login.html").forward(req,resp);

此时再直接访问"login.html"就不起作用了,因为此时的servlet相当于位于根目录下的test文件夹中,而login.html位于根目录下,因此此时通过相对路径就不能访问到login.html,若此时要访问login.html,需要将请求的地址改为"…/login.html","…/"代表返回上一层,对这个例子来讲就是返回到根目录(上一层),然后再访问这一层的login.html即可。

	req.getRequestDispatcher("../login.html").forward(req,resp);

同理,使用注解与上面的情况完全相同,只需要关注注解中的属性url-pattern与目标文件的相对路径即可。

	// Servlet注解
	@WebServlet(urlPatterns = "/test/dis")
	
	// 请求转发
	req.getRequestDispatcher("../login.html").forward(req,resp);

3、"/"出现在JSP页面中的表单标签或超链接标签中

如果是JSP页面向servlet进行跳转,这很明显,是浏览器请求服务器,因此,此时的""指的就是Tomcat服务器,所以若此时想要请求某个Servlet,最好使用相对路径,相对路径为该jsp与对应servlet所处的相对位置。在webapp下新建一个test.jsp,使用相对路径即可访问到Dispatcher类(后续Dispatcher在通过请求转发访问login.html)

	<a href="test/dis">hello</a>

若要使用绝对路径,"/"代表Tomcat服务器,有两种方式,要么给前面加上该项目的路径,要么自定义当前jsp页面的path与basePath属性后在网页中使用。

	//	加上项目路径
	<a href="/practice_webapp/test/dis">hello</a>
	
	//	使用自定义path属性
		// 设置basePath
		<%
	        String path = request.getContextPath();
	        String basePath = request.getScheme()+"://"+request.getServerName()
	            +":"+request.getServerPort()+path+"/";
	    %>
    	// 在<head>中设置默认路径为当前项目
    	<base href="<%=basePath%>"/>
    	// 在<a>标签中使用
    	<a href="test/dis">hello</a>

即便是使用basePath后,也只是相当于当前处于项目的根目录,但"/“指的仍然是Tomcat服务器的根目录,因此只能使用"test/dis"找到对应servlet,而不能使用”/test/dis"(前面加了个"/")。

本文参考:Servlet路径跳转问题

【JavaWeb开发】“web应用程序的根目录“与“web站点的根目录“的分析

在参考了这篇博文后我陷入了迷惑,什么是web应用程序的根目录?什么又是web站点的根目录?为何在我的intellij idea上跑的web项目根本没用到web站点根目录呢?
javaweb站点根目录和web应用根目录应用场景
先声明:本博客的web环境是java EE 之 Web Application 4.0,tomcat 版本为9;算是最新版本的普通web项目了,如果有什么不一样的地方,那一定是版本的错

1 开门见山

新建一个tomcat web项目,配置tomcat的虚拟目录,取默认值(/项目名_war_exploded)
在这里插入图片描述

那么如果你的tomcat的默认站点(即http://localhost:8080)没有更改的话,这个项目的

  • web站点根目录为:http://localhost:8080
  • web应用的根目录为:http://localhost:8080/WebPathDemo_war_exploded

小注意:根目录跟目录的概念不要混淆:
根目录代表的是从最底层目录访问到当前目录,即绝对路径;
目录代表的是当前目录(当前所在文件夹的名称)。

2 查看web应用的根目录的方法

第一种方式查看:
转到tomcat的Server,我们的URL就相当于web应用的根目录(去掉“/”才算当前目录)
在这里插入图片描述

第二种方式查看:
在sevlet中使用request.getContextPath();查看,查看的是web应用的相对目录

package org.hc.webpathdemo;

@WebServlet("/WebPath")
public class WebPath extends HttpServlet {

    private static final long serialVersionUID = -8249667430606104921L;

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws
     ServletException, IOException {
        //得到web应用的相对地址
        String contextPath = request.getContextPath();// 得到“/WebPathDemo_war_exploded”
        System.out.println("得到web应用的相对地址为:" + contextPath);
    }

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

浏览器访问http://localhost:8080/WebPathDemo_war_exploded/WebPath
控制台输出结果为得到web应用的相对地址为:/WebPathDemo_war_exploded

request.getContextPath();告诉了我们**web应用的相对目录**,相对于谁呢?相对于**web站点根目录**:http://localhost:8080

那么一切似乎清晰了,"web应用的根目录"就是在"web站点的根目录"后加入tomcat配置的虚拟目录 (Deployment的Application Context的设置的地址);

3 搞清楚什么时候是根据web站点根目录作为相对目录,什么时候是根据web应用根目录作为相对目录

3.1 如何访问资源

访问一个资源,一定是相对于web应用根目录的,比如在我这个项目中,一定是
http://localhost:8080/WebPathDemo_war_exploded/资源名路径(servlet或者html、jsp),才能访问资源。

  1. 比如我访问demo1下的index1.jsp,是必须要带上web应用根目录在前方的
    在这里插入图片描述

  2. 直接使用web站点根目录访问,是访问不到的
    在这里插入图片描述

3.2 a标签,jsp的include,form表单等究竟相对于哪个目录?

拿a标签举例子:
1.web目录下有两个jsp:
在这里插入图片描述

2.代码:
index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index.jsp</title>
</head>
<body>
	我是index.jsp<br />
<a href="index1.jsp">index1.jsp</a>
</body>
</html>

index1.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index1.jsp</title>
</head>
<body>
	我是index1.jsp
</body>
</html>

3.这样我在index里点a标签可以跳到index1,是理所当然的。
在这里插入图片描述
在这里插入图片描述

在a标签里直接写跳转的资源名,如index.jsp,观察地址栏发现,它相对的路径是
http://localhost:8080/WebPathDemo_war_exploded/,也就是web应用根目录

4.更改a标签跳转地址为/index1.jsp

<a href="/index1.jsp">index1.jsp</a>

查看结果:

在这里插入图片描述

在a标签里写跳转的“/”+资源名,如/index.jsp,观察地址栏发现,它相对的路径是
http://localhost:8080/,也就是web站点根目录,前面已经说过了,资源只有web应用根目录才能访问,相对于站点是访问不到资源的。

那么如果非要相对于站点如何访问呢?需要加入web应用的相对目录,这样写:

<a href="/WebPathDemo_war_exploded/index1.jsp">index1.jsp</a>

3.3 根据“/”判断是相对于站点还是应用

综上所述,a标签内的相对于web站点根目录还是web应用根目录的判断条件是,最前方有没有“/”

  • 无“/”,代表是相对于web应用根目录,即http://localhost:8080/tomcat配置的虚拟目录/
  • 有“/”,代表是相对于web站点根目录,即http://localhost:8080/

jsp的include、form表单等等也是如此的判断条件。

4.什么是虚拟目录?

tomcat的配置中Deploment的Application context是配置当前项目的虚拟目录,它是实际物理路径的映射。我们可以通过http://localhost:8080/WebPathDemo_war_exploded/demo1/index1.jsp访问一个jsp,那么这个jsp必须在我的本地物理路径上存在,才能访问成功,那么tomcat究竟去哪里寻找这个jsp呢?

答案就在编译后产生的artifacts中,tomcat将实际物理路径映射成了简单的虚拟目录,可以更方便的访问物理路径

编译后打开out(或target)/artifacts
在这里插入图片描述

可以看到项目中所有需要发布的资源都集中在out(或target)/artifacts/WebPathDemo_war_exploded这个文件夹中(部分人的out可能是target),artifacts就是发布项目的关键,可以从项目结构中对它进行重命名。
在这里插入图片描述

这里就是tomcat配置的虚拟目录所真正访问到的实际物理路径

总结

  1. 资源一定是相对于web应用根目录才能访问
  2. web站点根目录一般默认为:http://localhost:8080
  3. web应用根目录一般默认为:
  • web站点根目录/web应用目录
  • http://localhost:8080/tomcat配置的虚拟目录
  1. 根据“/”来判断是相对于web站点根目录还是web应用根目录:
  • 无“/”,代表是相对于web应用根目录
  • 有“/”,代表是相对于web站点根目录
  1. tomcat虚拟目录一般默认为:/项目名_war_exploded
  2. tomcat虚拟目录实际上为本机上实际物理路径的映射,默认为:

一般而言,对于路径由服务器的Servlet来处理,“/” 代表着的是web应用的根路径。比如请求转发,web.xml中的路径url-pattern路径配置,都是由web服务器来调用执行的。对于由浏览器进行解析的情况,如a标签、表单提交,请求重定向,则代表的web站点的根目录。

2021-11-18补充:

本文中的"web应用程序的根目录"与"web站点的根目录"后跟着的资源名都是使用的”相对于“这个词语,该词语的意思是这个资源名还具备本身的路径,比如我的index.jsp在web下的demo1文件夹里,那这个资源的路径就是/demo1/index.jsp,那他的全路径就是web应用根目录/demo1/index.jsp,这一点不用混淆。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/459786.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分布式ID解决方案对比

在复杂的分布式系统中&#xff0c;往往需要对大量的数据进行唯一标识&#xff0c;比如在对一个订单表进行了分库分表操作&#xff0c;这时候数据库的自增ID显然不能作为某个订单的唯一标识。除此之外还有其他分布式场景对分布式ID的一些要求&#xff1a; 趋势递增&#xff1a; …

(栈和队列) 232. 用栈实现队列 ——【Leetcode每日一题】

❓232. 用栈实现队列 难度&#xff1a;中等 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾int pop() 从队列…

Jenkins之allure测试报告邮件通知

Jenkins入门教程&#xff1a;Jenkins入门 一般情况下&#xff0c;我们想让Jenkins将构建结果或构建中的代码执行结果&#xff08;比如跑批数据&#xff09;通知我们&#xff0c;这个是构建后的操作。 经常用的是邮件通知 邮件通知基础 Jenkins自带了邮件通知配置&#xff0c…

灌区信息化和灌区自动化监测方案

一、方案背景 以提升粮食综合生产能力和水资源高效利用作为现代化改造的目标&#xff0c;把国家粮食安全和节水放在首位&#xff1b;以完善灌区工程设施体系和管理体系作为现代化改造的基础&#xff0c;以现代信息技术应用、智慧灌区建设作为提高管理能力和服务水平的手段&…

windows 文件夹目录过长超过长度259字符 文件打不开

当路径超过260个字符时&#xff0c;Windows操作系统就无法处理文件或文件夹&#xff0c;并且无法打开或重命名。这是因为Windows系统使用的文件系统&#xff0c;即FAT和NTFS文件系统&#xff0c;都有最大路径限制。NTFS文件系统最大长度限制为32767个字符&#xff0c;但操作系统…

算法训练day4:栈与队列

那么我这里再列出四个关于栈的问题&#xff0c;大家可以思考一下。以下是以C为例&#xff0c;使用其他编程语言的同学也对应思考一下&#xff0c;自己使用的编程语言里栈和队列是什么样的。 C中stack 是容器么&#xff1f;我们使用的stack是属于哪个版本的STL&#xff1f;我们…

FPGA基于XDMA实现PCIE X8采集AD9226数据 提供工程源码和QT上位机程序和技术支持

目录 1、前言2、我已有的PCIE方案3、PCIE理论4、总体设计思路和方案5、vivado工程详解6、驱动安装7、QT上位机软件8、上板调试验证9、福利&#xff1a;工程代码的获取 1、前言 PCIE&#xff08;PCI Express&#xff09;采用了目前业内流行的点对点串行连接&#xff0c;比起 PC…

就这些了, 常见 6 款API 文档工具推荐

8年开发经验&#xff0c;想分享一下我接触到这些 API 文档工具&#xff1a; Swagger: Swagger 是一个开源的 API 文档管理工具&#xff0c;可以通过注解自动生成 API 文档&#xff0c;并提供交互式 UI 和 API 调试功能。 Swagger 支持多种语言和格式&#xff0c;包括 Java、Pyt…

Linux没网络的情况下快速安装依赖或软件(挂载本地yum仓库源(Repository))

一、上传iso系统镜像&#xff1a; 上传和系统同一版本、同一位数&#xff08;32bit&#xff1a;i686或i386/64bit:x86_64&#xff09;的系统&#xff0c;不能是Minimal版本&#xff0c;可以是DVD&#xff08;较全&#xff09;或everything&#xff08;最全&#xff09;。 注&am…

Android移除sdk中的权限

有些第三方sdk中的敏感权限会给我们上架带来困扰&#xff0c;比如&#xff1a;QUERY_ALL_PACKAGES权限会导致上架Google play被拒。 案例&#xff1a;<uses-permission android:name"android.permission.QUERY_ALL_PACKAGES" /> 在app下的Manifest中并没有添加…

linux编译安装python的全过程,pip python不与linux系统环境混乱

因为使用要求&#xff0c;使得我需要在linux环境下安装一个独立的python环境&#xff0c;不干扰其他环境。 预安装 在安装python之前&#xff0c;请在linux系统下安装下面这些包&#xff1a; sudo apt-get install namelibssl-dev libcurl4 libcurl4-openssl-dev zlib-devel…

Zynq-7000、国产zynq-7000的GPIO控制(一)

Zynq-7000系列GPIO排布如下图所示&#xff0c;著名手册ug585第14章&#xff0c;第一个图&#xff0c;这图很清晰的表明&#xff0c;一共54个MIO&#xff0c;64个EMIO&#xff0c;所有这些IO共分为4个bank&#xff0c;其中 Bank0 32bit —>> MIO[0:31] Bank1 22bit —…

【移动端网页布局】流式布局案例 ② ( 实现顶部固定定位提示栏 | 布局元素百分比设置 | 列表样式设置 | 默认样式设置 )

文章目录 一、样式测量及核心要点1、样式测量2、高度设定3、列表项设置4、设置每个元素的百分比宽度5、设置图像宽度 二、核心代码编写1、HTML 标签结构2、CSS 样式3、展示效果 三、完整代码示例1、HTML 标签结构2、CSS 样式3、展示效果 一、样式测量及核心要点 1、样式测量 京…

8、接口的高级用法

1、索引类型 我们可以使用接口描述索引的类型和通过索引得到的值的类型&#xff0c;比如一个数组[‘a’, ‘b’]&#xff0c;数字索引0对应的通过索引得到的值为’a’。我们可以同时给索引和值都设置类型&#xff0c;看下面的示例&#xff1a; interface RoleDic {[id: number…

现在的00后,真是卷死了呀,想离职了·····

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。这不&#xff0c;刚开年我们公司来了个00后&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪23K&#xff0c;都快接近我了。 后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。 …

Spring Aop原理全面详解汇总

文章目录 近期想法什么是AOPSpringAOP与AspectjSpringAOP体系概述概念详解连接点- Jointpoint切入点- Pointcut通知- Advice切面- Aspect织入- Weaving 实现原理—动态代理JDK动态代理描述原理代码示例注意执行结果 优点缺点 CGLib动态代理描述原理代码示例注意执行结果 优点缺…

《数理天地》期刊简介及投稿邮箱

《数理天地》期刊简介及投稿邮箱 《数理天地》用稿以数学、物理、学科交叉、科普等稿件为主&#xff0c;自创刊以来&#xff0c;以新观点、新方法、新材料为主题&#xff0c;坚持"期期精彩、篇篇可读"的理念。数理天地内容详实、观点新颖、文章可读性强、信息量大&a…

操作系统——第一章概论(上)

未闻花名&#xff0c;不见花开 文章目录 1.1.1 操作系统的概念&#xff0c;功能1.1.2 操作系统的特征1.2 操作系统的发展和分类1.3.1 操作系统的运行机制1.3.2 中断和异常 1.1.1 操作系统的概念&#xff0c;功能 通过下图可以发现用户和操作系统是有一部分是相连的&#xff0c…

锁屏密码忘记了?教你40秒破iphone锁屏密码!

案例&#xff1a;iPhone锁屏密码忘记了怎么办&#xff1f; 【求助&#xff0c;昨晚刚改的锁屏密码&#xff0c;今早起来想不起来了。苹果锁屏密码有什么方法可以破解吗&#xff1f;】 当你忘记了iPhone的锁屏密码&#xff0c;可能会感到困惑和无助。本文将介绍40秒破iphone锁屏…

从Redis到KeyDB:实现高可用和高可扩展性的转变

文章目录 从Redis到KeyDB&#xff1a;实现高可用和高可扩展性的转变特点**[线程模型]( )****[链接管理]( )****[锁机制]( )****[Active-Replica]( )** 结语 从Redis到KeyDB&#xff1a;实现高可用和高可扩展性的转变 今天给大家介绍的是KeyDB&#xff0c;KeyDB项目是从redis f…