歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

在Java Web中相對路徑和絕對路徑區別及應用方法

閒來無事,研究了一下bootstrap框架,並把這個框架融入到我開發的一個項目中,在應用過程中發現了一些問題,經過潛心研究這個問題終於解決了,下面我就把整個過程分享給大家。

一、開發環境介紹

開發語言   JDK1.8 IDE ECLIPSE platform 4.6.0 WEB容器 

tomcat9

後端框架 Spring+Spring MVC+Spring Data 前端框架 bootstrap3.3.7

二、問題回顧

1、項目說明

 

2、static.html文件(改成jsp文件也可以)

 注意:紅色框內容<link rel="stylesheet" href="css/bootstrap.min.css"/>,采用了相對路徑

運行效果:

現象一:

 現象二:

CSS樣式表文件沒有起作用。查看源代碼,點擊CSS連接,如下圖:

三、解決方案

1、針對“現象一”的解決方案

在/OutSourcingManage/WebContent/WEB-INF/dispatcherServlet-servlet.xml文件中加入如下語句:

<mvc:default-servlet-handler/>

2、針對“現象二”的解決方案

方法一、在/OutSourcingManage/WebContent/WEB-INF/dispatcherServlet-servlet.xml文件中加入如下語句:

<mvc:resources mapping="/css/**" location="/bootstrap/css/"/>

方法二、修改static.html,將“<link rel="stylesheet" href="css/bootstrap.min.css"/>”修改為:

<link rel="stylesheet" href="/OutSourcingManage/bootstrap/css/bootstrap.min.css"/>

方法三、將static.html修改static.jsp,並增加如下語句:

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<head>

<base href="<%=basePath%>">

....

四、原理剖析

1、目標效果

2、內部原理剖析

(1)靜態資源的處理

 

Spring MVC的攔截器DispatcherServlet默認是攔截所有請求,包括*.js、*.css、*.html、*.jpg、*.jsp等靜態資源和動態資源,但是靜態資源沒有對應的handler,所以會出現上述警告。為了解決這個問題,需要為*.js、*.css、*.html、*.jpg等靜態資源配置tomcat默認的攔截器。而<mvc:default-servlet-handler/>就是為此目的而生。

(2)絕對路徑、相對路徑

關於絕對路徑、相對路徑對於很多初學者感到迷惑,即使寫出了可以運行的程序,也沒有真正搞清楚原理,甚至對某些老手,也偶爾會犯迷糊。我總結了一些認識規則,與各位分享。

  • URL的一般語法格式為:
URL由三部分組成:資源類型、存放資源的主機域名、資源文件名。 (帶方括號[]的為可選項):protocol:// hostname[:port] / path / [;parameters][?query]#fragment protocol(協議):一般是ftp、file、http(https)、mailto、thunder等協議。 hostname(主機名):是指存放資源的服務器的DNS(域名服務器)主機名或IP地址。有時,在主機名前也可以包含連接到服務器所需的用戶名和密碼(格式:username:password@hostname)。 port(端口號):各種傳輸協議都有默認的端口號,如http的默認端口為80,我們在開發過程中一般采用8080。 path(路徑):由零或多個“/”符號隔開的字符串,一般用來表示主機上的一個目錄或文件地址。 parameters(參數):這是用於指定特殊參數的可選項。 query(查詢):用於傳遞參數,可有多個參數,用“&”符號隔開,每個參數的名和值用“=”符號隔開。 fragment(信息片段):用於指定網絡資源中的片段。 以http請求為例,URL地址是http://192.168.0.1:8080/OutSourcingManage/login?username=gaodianhua&password=123456
  • URL格式細分含義

http:/主機名:[端口號]/web應用根目錄/資源名稱[?query]。

下面以http://192.168.0.1:8080/OutSourcingManage/login?username=gaodianhua&password=123456為例

①服務器根地址(或稱為tomcat服務器地址)規范為:

http:/主機名:[端口號]/,例如:http://192.168.0.1:8080/

②web應用根地址規范為:

http:/主機名:[端口號]/web應用根目錄/,例如:http://192.168.0.1:8080/OutSourcingManage/

③資源根地址規范為:

http:/主機名:[端口號]/web應用根目錄/資源名稱,例如:http://192.168.0.1:8080/OutSourcingManage/login

請記住:上面三個概念,即:tomcat服務器根地址、web應用根地址、資源根地址 

  • 服務器端(tomcat)和客戶端(浏覽器)對URL地址的解析規則

對於請求的任何資源,均需要轉化為絕對URL地址。

服務器端對URL地址的解析一般使用web應用根地址作為相對路徑。例如頁面跳轉和重定向時使用的地址:

request.getRequestDispatcher("/WEB-INF/views/success.jsp").forward(request, res);//頁面跳轉,跳轉成功

request.getRequestDispatcher("WEB-INF/views/success.jsp").forward(request, res);//頁面跳轉,跳轉成功

response.sendRedirect("/hello.html");//重定向,重定向失敗

response.sendRedirect("hello.html");//重定向,重定向成功

"/"在服務器端和客戶端的處理規則是不同的,即:

  1. 在服務器端解析時,被認為是以web應用根地址為基准地址的相對路徑。
  2. 在客戶端解析時,被認為是tomcat服務器根地址。

相對路徑即不帶"/"時,在服務器端和客戶端的處理規則則是相同的,即:

  1. 在服務器端解析時,被認為是web應用根的地址。
  2. 在客戶端解析時,被認為是父頁面請求時web應用根地址為基准地址的相對地址。

下面以hello.html測試可得:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<H1>Hello World</H1>
<a href="world.html">測試相對地址</a>
<a href="/world.html">測試絕對地址</a>
</body>
</html>

注:world.html和hello.html在相同目錄下。

地址欄輸入:http://localhost:8080/OutSourcingManage/hello.html,其中,"http://localhost:8080/OutSourcingManage/"為web應用根地址。

點擊"測試相對地址"時,地址欄顯示的是:http://localhost:8080/OutSourcingManage/world.html(請求成功)

點擊"測試絕對地址"時,地址欄顯示的是:http://localhost:8080/world.html(請求失敗,此時要想成功需要手工補充web應用地址)

如果地址欄輸入:http://localhost:8080/OutSourcingManage/springmvc/hello.html,其中,"http://localhost:8080/OutSourcingManage/"為web應用根地址。

點擊"測試相對地址"時,地址欄顯示的是:http://localhost:8080/OutSourcingManage/springmvc/world.html(請求成功)

點擊"測試絕對地址"時,地址欄顯示的是:http://localhost:8080/world.html(請求失敗,此時要想成功需要手工補充web應用地址)

注意:①頁面跳轉(forward)是以web應用根地址為基准的,可以跳轉到同應用下任意有效資源頁面。

         ②WEB-INF只能被服務器端訪問,不能被客戶端訪問。

         ③重定向(sendRedirect)是服務器向客戶端響應的資源名稱,由客戶端重新向服務器端請求。

         ④重定向可以跨web應用。

         ⑤基准路徑或者叫相對路徑的基准:生手開車時,經常出現會問一個問題:"我的方向盤向左方(或向右方)打了半圈,還是一圈,還是打死了?",教練常常會告訴我,如果記不清了就把方向盤打死,然後回一圈半,方向盤就正了。同樣,在操作系統中,可以使用命令"pwd"查看當前所處的目錄。這些告訴我們基准路徑很重要。

(3)一點建議

由於在日常開發過程中,相對地址維護起來非常復雜,容易混亂,建議統一采用絕對地址。在html/jsp中有<base>標簽。利用該標簽可以實現絕對地址訪問。以JSP文件為例:(注意紅色字體部分)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
<head>

      <base href="<%=basePath%>">

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Insert title here</title>
  <link rel="stylesheet" href="css/bootstrap.min.css"/>
</head>

<body>

 ....

五:總結

     終於寫完了,整整一天時間(國慶節第二天),雖有感覺有點累,但一想到知識傳播會幫助很多初學者,我心裡又是非常的高興。自己鼓勵一下自己吧。努力,加油。

分享是一種快樂,更是一種精神,我們生活在一個知識爆炸的社會,知識每天日新月異,我崇尚“工匠精神”,更喜歡“工程師文化”,把分享當作對自己的一種動力和督促,讓自己不放松、不舒適,每天都生活積極向上的進步中和對工作、生活的思考中,永不懈怠。一句話,我們永遠在路上,在築夢的路上。 我非常注重學習知識的基礎原理,探究系統背後的運作原理,運用知識體系化的學習方法,解決看似復雜的問題。有些問題就是那麼簡單,但其背後的原理卻非常復雜,這就是為什麼要學習的原因。學習不是為了“我會了,我懂了”,而是探究事物的本質和事物之間的聯系,提升自己的學習能力。我把一個人的知識體系看作一個“黑洞”,只有這個“黑洞”具有足夠大的質量和密度,才能源源不斷的吸收知識,學習速度和能力才能不斷提升。中國有句俗語“厚積薄發”,我想道理是相通的。 與各位有著同樣理念的小伙伴們共勉。

Copyright © Linux教程網 All Rights Reserved