Java Web中的include

上周在工作上遇到了一件糗事脆丁。在寫(xiě)jsp的過(guò)程中顺呕,經(jīng)常會(huì)遇到將jsp文件模塊化,然后通過(guò)include的方式將一個(gè)個(gè)模塊進(jìn)行組裝必指。這個(gè)過(guò)程中囊咏,經(jīng)常會(huì)在各個(gè)模塊之間共享變量,那么變量的范圍是什么呢塔橡?自己因?yàn)橥涍@個(gè)知識(shí)點(diǎn)而調(diào)試了好長(zhǎng)時(shí)間梅割。知識(shí)點(diǎn)雖然簡(jiǎn)單,但是這個(gè)是Java web經(jīng)典的問(wèn)題葛家,即對(duì)于include户辞,Java web到底是怎么實(shí)現(xiàn)的?

jsp文件到底是什么癞谒?

jsp-servlet-tomcat.png
  • JSP是Servlet的一種特殊形式底燎,每個(gè)JSP頁(yè)面就是一個(gè)Servlet實(shí)例
  • JSP頁(yè)面由系統(tǒng)編譯成Servlet刃榨,Servlet再負(fù)責(zé)響應(yīng)用戶請(qǐng)求
  • Tomcat負(fù)責(zé)執(zhí)行Servlet文件

準(zhǔn)備實(shí)驗(yàn)

因此在我機(jī)器上實(shí)驗(yàn)了一把,實(shí)驗(yàn)的環(huán)境如下:

名稱(chēng) 配置
系統(tǒng) Mac OS
IDE IntelliJ IDEA 2017.2 Help
容器 Tomcat 7.04

項(xiàng)目的文件路徑如下所示:

項(xiàng)目路徑.png

在Mac OS下双仍,Intellij IDEA將jsp文件編譯成相應(yīng)的servlet文件枢希,那么該文件的位置是:
/Users/garybhwang/Library/Caches/IntelliJIdea2017.2/tomcat
然后根據(jù)相應(yīng)的項(xiàng)目名稱(chēng)找到相應(yīng)的java文件:
/Unnamed_項(xiàng)目名/work/Catalina/localhost/_/org/apache/jsp
相應(yīng)的目錄結(jié)構(gòu)如下所示:

jsp-servlet目錄.png

實(shí)驗(yàn)方式

common.jsp 頁(yè)面去包含header.jsp 頁(yè)面,header.jsp 代碼如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>header</title>
</head>
<body>
    <h2>This is header page!</h2>
</body>
</html>

include三種方式

  • jsp頁(yè)面的include指令
    <%@ include file="/WEB-INF/header.jsp"%>
    common.jsp 頁(yè)面的代碼如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>common</title>
</head>
<body>
    <h1>This is common page!</h1>
    <%@ include file="/WEB-INF/header.jsp"%>
</body>
</html>

那么common.jsp 編譯成為servlet文件只有的內(nèi)容如下:

(common_jsp.java).png

從上面的源碼可以看到朱沃,<%@ include file = "*******" %>最終是將header.jsp 文件進(jìn)行編譯苞轿,然后將其內(nèi)容包含進(jìn)來(lái)。因此include指令包含的是頁(yè)面的內(nèi)容逗物。

  • jsp頁(yè)面的include動(dòng)作元素
    <jsp:include page="/WEB-INF/header.jsp"></jsp:include>
    common.jsp 頁(yè)面的代碼如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>common</title>
</head>
<body>
    <h1>This is common page!</h1>
    <jsp:include page="/WEB-INF/header.jsp"></jsp:include>
</body>
</html>

那么按照這種包含的方式搬卒,common.jsp 編譯的servlet源碼如下所示:

(common_jsp.java).png

從common_jsp.java的servlet文件中可以看到 <jsp:include page="*****"></jsp:include>,并不是像include指令那樣包含內(nèi)容翎卓,而是通過(guò)Tomcat容器中的JspRuntimeLibrary類(lèi)的include方法進(jìn)行包含契邀。查看Tomcat容器的源碼可以看到,可以看到:

tomcat 源碼.png

從Tomcat源碼可以分析出失暴,<jsp:include page="*****"></jsp:include>的實(shí)質(zhì)是坯门,在common_jsp.java 文件中,執(zhí)行 RequestDispatcher的include方法锐帜,而這個(gè)方法使得 common_jsp.java 中的request 對(duì)象、response對(duì)象和header.jsp中的response對(duì)象畜号、request對(duì)象是共享的缴阎。

  • RequestDispatcher類(lèi)的include方法
    request.getRequestDispatcher("/WEB-INF/header.jsp").include(request,response);
    同上分析。

include和共享對(duì)象

對(duì)象 作用
request 頁(yè)面和頁(yè)面構(gòu)成forward以及include關(guān)系简软,達(dá)成共享
pageContext 在一個(gè)頁(yè)面中共享
session 在整個(gè)會(huì)話期間共享

因此蛮拔,有上述的分析可以得出這樣的結(jié)論:

  • 對(duì)于 <%@ include file %> 而言,子頁(yè)面只是將內(nèi)容包含在父頁(yè)面之中痹升,因此只有子頁(yè)面和父頁(yè)面之間的request對(duì)象以及pageContext對(duì)象是共享的
  • 對(duì)于 <jsp:include path ></jsp:include>而言建炫,父頁(yè)面通過(guò)RequestDispatcher的include方法將子頁(yè)面包含進(jìn)來(lái),因此只有父頁(yè)面和子頁(yè)面之間request對(duì)象是共享的
include方式 父子頁(yè)面共享對(duì)象
<%@ include file %> pageContext對(duì)象以及request對(duì)象
<jsp:include path ></jsp:include><c:import></c:import> request對(duì)象疼蛾,不共享pageContext對(duì)象
RequestDispatcher類(lèi)的include方法 request對(duì)象肛跌,不共享pageContext對(duì)象
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市察郁,隨后出現(xiàn)的幾起案子衍慎,更是在濱河造成了極大的恐慌,老刑警劉巖皮钠,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稳捆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡麦轰,警方通過(guò)查閱死者的電腦和手機(jī)乔夯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)砖织,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人末荐,你說(shuō)我怎么就攤上這事侧纯。” “怎么了鞠评?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵茂蚓,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我剃幌,道長(zhǎng)聋涨,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任负乡,我火速辦了婚禮牍白,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抖棘。我一直安慰自己茂腥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布切省。 她就那樣靜靜地躺著最岗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪朝捆。 梳的紋絲不亂的頭發(fā)上般渡,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音芙盘,去河邊找鬼驯用。 笑死,一個(gè)胖子當(dāng)著我的面吹牛儒老,可吹牛的內(nèi)容都是我干的蝴乔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼驮樊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼薇正!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起囚衔,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤铝穷,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后佳魔,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體曙聂,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年鞠鲜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宁脊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片断国。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖榆苞,靈堂內(nèi)的尸體忽然破棺而出稳衬,到底是詐尸還是另有隱情,我是刑警寧澤坐漏,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布薄疚,位于F島的核電站,受9級(jí)特大地震影響赊琳,放射性物質(zhì)發(fā)生泄漏街夭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一躏筏、第九天 我趴在偏房一處隱蔽的房頂上張望板丽。 院中可真熱鬧,春花似錦趁尼、人聲如沸埃碱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)砚殿。三九已至,卻和暖如春芝囤,著一層夾襖步出監(jiān)牢的瞬間似炎,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工凡人, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留名党,地道東北人叹阔。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓挠轴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親耳幢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子岸晦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容