JavaWeb——Servlet路徑問題("/"到底代表什么)
JavaWeb——Servlet路徑問題("/"到底代表什么)
在JavaWeb中,使用路徑時出現(xiàn)了大量的"/“,而每次使用”“時都感覺其代表的含義是不同的,因此,本篇文章將匯總JavaWeb中的”"出現(xiàn)情況及其所代表的含義。
了解這些"/"含義之前,先來了解絕對路徑與相對路徑的概念。
提前說一下自己總結(jié)的規(guī)律:
只要是服務(wù)器(tomcat vscde本地程序運行后的server )以及open with liveServer)的話,/都是指的是服務(wù)器的根路徑
一般而言,對于路徑由服務(wù)器的Servlet來處理,“/” 代表著的是web應(yīng)用的根路徑。比如請求轉(zhuǎn)發(fā),web.xml中的路徑url-pattern路徑配置,都是由web服務(wù)器來調(diào)用執(zhí)行的。對于由瀏覽器進行解析的情況,如a標(biāo)簽、表單提交,請求重定向,則代表的web站點的根目錄。
若是**
瀏覽器中請求服務(wù)器**
,則此時絕對路徑的"/“代表的是**
服務(wù)器(Tomcat)的根目錄**
,而此時的相對路徑代表的是**
該項目的根目錄**
?? 若在**
服務(wù)器中請求服務(wù)器**
,則此時絕對路徑的”/"或相對路徑代表的都是該項目的根目錄
?? 而在服務(wù)器內(nèi)部,可以這樣理解,服務(wù)器在解析路徑時,‘src’、'webapp’這些文件夾其實都被忽略了,也就是說,這兩個目錄下的文件可以認為是在同一目錄(該項目的根目錄)下
。
??一定要看使用的是什么路徑,如果是相對路徑,只需要看目標(biāo)文件與當(dāng)前文件之間的位置關(guān)系即可,而如果是絕對路徑,才需要注意上面這幾點要求。
1、"/"出現(xiàn)在請求重定向與請求轉(zhuǎn)發(fā)中
有關(guān)請求轉(zhuǎn)發(fā)與請求重定向的概念,這里不再贅述,請參考:請求轉(zhuǎn)發(fā)與請求重定向。
由于請求轉(zhuǎn)發(fā)是服務(wù)器內(nèi)部行為,是在服務(wù)器中請求服務(wù)器,因此
請求轉(zhuǎn)發(fā)中的"/"表示該項目的根目錄
由于請求重定向是瀏覽器行為,是在瀏覽器中請求服務(wù)器,因此
請求重定向的"/"表示Tomcat服務(wù)器的根目錄
先來看請求轉(zhuǎn)發(fā),此時dispatcher.jsp與request_form.jsp由于上面第三條的存在,都處于該項目的根目錄,因此若使用絕對路徑,可以再dispatcher.jsp中使用"/request_form.jsp"訪問到request_form.jsp,若使用相對路徑,由于dispatcher.jsp與request_form.jsp同在一個目錄(項目根目錄)下,因此也可以直接使用"request_form.jsp"訪問到request_form.jsp。
// 請求轉(zhuǎn)發(fā)使用下面兩種方式均可以訪問到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服務(wù)器的根目錄,因此要想訪問該項目根目錄中的文件,需要加上該項目根目錄路徑(需要與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、"/"出現(xiàn)在web.xml文件中(中的)
servlet的相對路徑跳轉(zhuǎn)是相對于servlet配置的xml路徑(或servlet3.0注解路徑),無論是使用配置文件的方式還是注解的方式,在描述絕對路徑的時候就不要多說,此時不需要知道servlet到底在哪,而只需要知道目標(biāo)文件在哪即可,若servlet和目標(biāo)文件都在同一服務(wù)器中,就相當(dāng)于是服務(wù)器內(nèi)部請求(請求轉(zhuǎn)發(fā)或重定向均可),若servlet和目標(biāo)文件在不同服務(wù)器中,使用請求重定向即可。
若servlet與目標(biāo)文件處于同一服務(wù)器中,并且是以相對路徑來調(diào)用,無論是配置文件還是注解,只需要servlet的url-pattern(注解里也有)與目標(biāo)文件的相對位置
即可。舉個栗子:
// 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)中的請求轉(zhuǎn)發(fā)
req.getRequestDispatcher("login.html").forward(req,resp);
解析一下這個例子,此時的servlet根據(jù)配置文件的url-pattern配置可以看出,該servlet的路徑相當(dāng)于是在"/dis",即當(dāng)前項目的根目錄下(起了個名字叫dis),而login.html也是處于當(dāng)前項目的根目錄,因此使用相對路徑訪問直接"login.html"即可。
??還是同樣的結(jié)構(gòu)圖,將配置文件中的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)中的請求轉(zhuǎn)發(fā)
req.getRequestDispatcher("login.html").forward(req,resp);
此時再直接訪問"login.html"就不起作用了,因為此時的servlet相當(dāng)于位于根目錄下的test文件夾中,而login.html位于根目錄下,因此此時通過相對路徑就不能訪問到login.html,若此時要訪問login.html,需要將請求的地址改為"…/login.html","…/"代表返回上一層,對這個例子來講就是返回到根目錄(上一層),然后再訪問這一層的login.html即可。
req.getRequestDispatcher("../login.html").forward(req,resp);
同理,使用注解與上面的情況完全相同,只需要關(guān)注注解中的屬性url-pattern與目標(biāo)文件的相對路徑即可。
// Servlet注解
@WebServlet(urlPatterns = "/test/dis")
// 請求轉(zhuǎn)發(fā)
req.getRequestDispatcher("../login.html").forward(req,resp);
3、"/"出現(xiàn)在JSP頁面中的表單標(biāo)簽或超鏈接標(biāo)簽中
如果是JSP頁面向servlet進行跳轉(zhuǎn),這很明顯,是瀏覽器請求服務(wù)器,因此,此時的""指的就是Tomcat服務(wù)器,所以若此時想要請求某個Servlet,最好使用相對路徑,相對路徑為該jsp與對應(yīng)servlet所處的相對位置。在webapp下新建一個test.jsp,使用相對路徑即可訪問到Dispatcher類(后續(xù)Dispatcher在通過請求轉(zhuǎn)發(fā)訪問login.html)
<a href="test/dis">hello</a>
若要使用絕對路徑,"/"代表Tomcat服務(wù)器,有兩種方式,要么給前面加上該項目的路徑,要么自定義當(dāng)前jsp頁面的path與basePath屬性后在網(wǎng)頁中使用。
// 加上項目路徑
<a href="/practice_webapp/test/dis">hello</a>
// 使用自定義path屬性
// 設(shè)置basePath
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()
+":"+request.getServerPort()+path+"/";
%>
// 在<head>中設(shè)置默認路徑為當(dāng)前項目
<base href="<%=basePath%>"/>
// 在<a>標(biāo)簽中使用
<a href="test/dis">hello</a>
即便是使用basePath后,也只是相當(dāng)于當(dāng)前處于項目的根目錄,但"/“指的仍然是Tomcat服務(wù)器的根目錄,因此只能使用"test/dis"找到對應(yīng)servlet,而不能使用
”/test/dis"(前面加了個"/")。
本文參考:Servlet路徑跳轉(zhuǎn)問題
【JavaWeb開發(fā)】“web應(yīng)用程序的根目錄“與“web站點的根目錄“的分析
在參考了這篇博文后我陷入了迷惑,什么是web應(yīng)用程序的根目錄?什么又是web站點的根目錄?為何在我的intellij idea上跑的web項目
根本沒用到web站點根目錄呢?
javaweb站點根目錄和web應(yīng)用根目錄應(yīng)用場景
先聲明:本博客的web環(huán)境是java EE 之 Web Application 4.0,tomcat 版本為9;算是最新版本的普通web項目了,如果有什么不一樣的地方,那一定是版本的錯
1 開門見山
新建一個tomcat web項目,配置tomcat的虛擬目錄,取默認值(/項目名_war_exploded)
那么如果你的tomcat的默認站點(即http://localhost:8080)沒有更改的話,這個項目的
- web站點根目錄為:http://localhost:8080
- web應(yīng)用的根目錄為:http://localhost:8080/WebPathDemo_war_exploded
小注意:根目錄跟目錄的概念不要混淆:
根目錄代表的是從最底層目錄訪問到當(dāng)前目錄,即絕對路徑;
目錄代表的是當(dāng)前目錄(當(dāng)前所在文件夾的名稱)。
2 查看web應(yīng)用的根目錄的方法
第一種方式查看:
轉(zhuǎn)到tomcat的Server,我們的URL就相當(dāng)于web應(yīng)用的根目錄(去掉“/”才算當(dāng)前目錄)
第二種方式查看:
在sevlet中使用request.getContextPath();
查看,查看的是web應(yīng)用的相對目錄
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應(yīng)用的相對地址
String contextPath = request.getContextPath();// 得到“/WebPathDemo_war_exploded”
System.out.println("得到web應(yīng)用的相對地址為:" + contextPath);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
doPost(request, response);
}
}
瀏覽器訪問http://localhost:8080/WebPathDemo_war_exploded/WebPath
控制臺輸出結(jié)果為得到web應(yīng)用的相對地址為:/WebPathDemo_war_exploded
request.getContextPath();告訴了我們**web應(yīng)用的相對目錄**,相對于誰呢?相對于**web站點根目錄**:
http://localhost:8080
那么一切似乎清晰了,"web應(yīng)用的根目錄"
就是在"web站點的根目錄"
后加入tomcat配置的虛擬目錄 (Deployment的Application Context的設(shè)置的地址);
3 搞清楚什么時候是根據(jù)web站點根目錄
作為相對目錄,什么時候是根據(jù)web應(yīng)用根目錄
作為相對目錄
3.1 如何訪問資源
訪問一個資源,一定是相對于web應(yīng)用根目錄的
,比如在我這個項目中,一定是http://localhost:8080/WebPathDemo_war_exploded
/資源名路徑(servlet或者html、jsp),才能訪問資源。
-
比如我訪問demo1下的index1.jsp,是必須要帶上web應(yīng)用根目錄在前方的
-
直接使用web站點根目錄訪問,是訪問不到的
3.2 a標(biāo)簽,jsp的include,form表單等究竟相對于哪個目錄?
拿a標(biāo)簽舉例子:
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標(biāo)簽可以跳到index1,是理所當(dāng)然的。
在a標(biāo)簽里直接寫跳轉(zhuǎn)的資源名
,如index.jsp,觀察地址欄發(fā)現(xiàn),它相對的路徑是http://localhost:8080/WebPathDemo_war_exploded/
,也就是web應(yīng)用根目錄
4.更改a標(biāo)簽跳轉(zhuǎn)地址為/index1.jsp
<a href="/index1.jsp">index1.jsp</a>
查看結(jié)果:
在a標(biāo)簽里寫跳轉(zhuǎn)的“/”+資源名
,如/index.jsp,觀察地址欄發(fā)現(xiàn),它相對的路徑是http://localhost:8080/
,也就是web站點根目錄,前面已經(jīng)說過了,資源只有web應(yīng)用根目錄才能訪問,相對于站點是訪問不到資源的。
那么如果非要相對于站點如何訪問呢?需要加入web應(yīng)用的相對目錄,這樣寫:
<a href="/WebPathDemo_war_exploded/index1.jsp">index1.jsp</a>
3.3 根據(jù)“/”判斷是相對于站點還是應(yīng)用
綜上所述,a標(biāo)簽內(nèi)的相對于web站點根目錄還是web應(yīng)用根目錄的判斷條件是,最前方有沒有“/”
- 無“/”,代表是相對于
web應(yīng)用根目錄
,即http://localhost:8080/tomcat配置的虛擬目錄/
- 有“/”,代表是相對于
web站點根目錄
,即http://localhost:8080/
jsp的include、form表單等等也是如此的判斷條件。
4.什么是虛擬目錄?
tomcat的配置中Deploment的Application context是配置當(dāng)前項目的虛擬目錄,它是實際物理路徑的映射。我們可以通過http://localhost:8080/WebPathDemo_war_exploded/demo1/index1.jsp
訪問一個jsp,那么這個jsp必須在我的本地物理路徑上存在,才能訪問成功,那么tomcat究竟去哪里尋找這個jsp呢?
答案就在編譯后產(chǎn)生的artifacts中,tomcat將實際物理路徑映射成了簡單的虛擬目錄,可以更方便的訪問物理路徑
編譯后打開out(或target)/artifacts
可以看到項目中所有需要發(fā)布的資源都集中在out(或target)/artifacts/WebPathDemo_war_exploded
這個文件夾中(部分人的out可能是target),artifacts就是發(fā)布項目的關(guān)鍵,可以從項目結(jié)構(gòu)中對它進行重命名。
這里就是tomcat配置的虛擬目錄所真正訪問到的實際物理路徑了
總結(jié)
- 資源一定是相對于
web應(yīng)用根目錄
才能訪問 - web站點根目錄一般默認為:
http://localhost:8080
- web應(yīng)用根目錄一般默認為:
- web站點根目錄/web應(yīng)用目錄
- 即
http://localhost:8080/tomcat配置的虛擬目錄
- 根據(jù)“/”來判斷是相對于web站點根目錄還是web應(yīng)用根目錄:
- 無“/”,代表是相對于
web應(yīng)用根目錄
- 有“/”,代表是相對于
web站點根目錄
- tomcat虛擬目錄一般默認為:
/項目名_war_exploded
- tomcat虛擬目錄實際上為本機上實際物理路徑的映射,默認為:
一般而言,對于路徑由服務(wù)器的Servlet來處理,“/” 代表著的是web應(yīng)用的根路徑。比如請求轉(zhuǎn)發(fā),web.xml中的路徑url-pattern路徑配置,都是由web服務(wù)器來調(diào)用執(zhí)行的。對于由瀏覽器進行解析的情況,如a標(biāo)簽、表單提交,請求重定向,則代表的web站點的根目錄。
2021-11-18補充:文章來源:http://www.zghlxwxcb.cn/news/detail-424998.html
本文中的"web應(yīng)用程序的根目錄"與"web站點的根目錄"后跟著的資源名都是使用的”相對于“這個詞語,該詞語的意思是這個資源名還具備本身的路徑,比如我的index.jsp在web下的demo1文件夾里,那這個資源的路徑就是/demo1/index.jsp
,那他的全路徑就是web應(yīng)用根目錄/demo1/index.jsp
,這一點不用混淆。文章來源地址http://www.zghlxwxcb.cn/news/detail-424998.html
到了這里,關(guān)于Servlet路徑問題(“/“到底代表什么)-“web應(yīng)用程序的根目錄“與“web站點的根目錄“的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!