閒來無事,研究了一下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)絕對路徑、相對路徑
關於絕對路徑、相對路徑對於很多初學者感到迷惑,即使寫出了可以運行的程序,也沒有真正搞清楚原理,甚至對某些老手,也偶爾會犯迷糊。我總結了一些認識規則,與各位分享。
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應用根地址、資源根地址
對於請求的任何資源,均需要轉化為絕對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");//重定向,重定向成功
"/"在服務器端和客戶端的處理規則是不同的,即:
相對路徑即不帶"/"時,在服務器端和客戶端的處理規則則是相同的,即:
下面以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>
....
五:總結
終於寫完了,整整一天時間(國慶節第二天),雖有感覺有點累,但一想到知識傳播會幫助很多初學者,我心裡又是非常的高興。自己鼓勵一下自己吧。努力,加油。
分享是一種快樂,更是一種精神,我們生活在一個知識爆炸的社會,知識每天日新月異,我崇尚“工匠精神”,更喜歡“工程師文化”,把分享當作對自己的一種動力和督促,讓自己不放松、不舒適,每天都生活積極向上的進步中和對工作、生活的思考中,永不懈怠。一句話,我們永遠在路上,在築夢的路上。 我非常注重學習知識的基礎原理,探究系統背後的運作原理,運用知識體系化的學習方法,解決看似復雜的問題。有些問題就是那麼簡單,但其背後的原理卻非常復雜,這就是為什麼要學習的原因。學習不是為了“我會了,我懂了”,而是探究事物的本質和事物之間的聯系,提升自己的學習能力。我把一個人的知識體系看作一個“黑洞”,只有這個“黑洞”具有足夠大的質量和密度,才能源源不斷的吸收知識,學習速度和能力才能不斷提升。中國有句俗語“厚積薄發”,我想道理是相通的。 與各位有著同樣理念的小伙伴們共勉。