淺析JSP頁面翻譯的原理
眾所周知,每一個JSP頁面都會被Web容器編譯成一個Java類,供Web容器調(diào)用,并且生成HTML葉面回饋給用戶。而了解其中的變異方法和規(guī)則,對我們學(xué)習(xí)JSP是非常有好處的,可以說學(xué)習(xí)好了這個編譯原理,就已經(jīng)學(xué)習(xí)好了大部分的JSP知識,剩下的工作就只剩下熟記一些tablib和反復(fù)應(yīng)用以使自己更加熟練而已了。
先來看一下JSP頁面所對應(yīng)的Class的基本結(jié)構(gòu)。每一個JSP頁面都會被編譯成成如下的格式樣子,先給一個大致的印象,詳細(xì)的說明在后面
這里面最重要的函數(shù)就是pageservice,web容器在編譯好一個JSP類以后,就申請這個類的對象,并且直接調(diào)用pageservice來獲得Response,最后返回給客戶。作為細(xì)節(jié),我們可以總結(jié)如下:
1.所有的JSP頁面翻譯出來的class,都從HttpJspBase繼承,并且命名為PageName$jsp。
2.在第一次調(diào)用pageservice函數(shù)的時候,該class會進行一次初始化,而這個初始化函數(shù)是_jspx_init,如果我們想,我們還可以自定義這個函數(shù),來實現(xiàn)JSP頁面的初始化。
3.<% %> 這樣的代碼被轉(zhuǎn)換成什么了?
這樣的代碼被直接轉(zhuǎn)成Java代碼放到pageservice函數(shù)里面。
4.<%! %> 這樣的代碼被轉(zhuǎn)換成什么了?
這樣的代碼被翻譯成成員函數(shù)和成員變量,也就是說,這些聲明在JSP的生命周期內(nèi)都是存在的。
5.HTML代碼呢?
html代碼直接被寫到PrintWriter里面回饋給用戶,非常的直接。
6.為什么JSP頁面翻譯有那么多省寫方式,比如說session , out , page , context之類。
這都是在pageservice里面定義的臨時變量,具體的初始化可以參看上面的例子代碼,每一次調(diào)用JSP頁面,這些變量都會被重新初始化一次。當(dāng)然我們也可以方便的聲明自己的變量。
7.省寫方式<%= object.doSomething()%> 這么理解?
這種省寫方式調(diào)用doSomething所得到的Object的toString(),然后直接寫到out里面。相當(dāng)于:
out.print(object.doSomethiing().toString())
8.JavaBean 里面的scope定義了作用域范圍,這個范圍在這里的意思是?
這是Bean對象句柄保存的地方的意思。我們可以想象一下,一個page范圍的Bean只是pageservice里面的一個局部變量,當(dāng)一次處理結(jié)束后,這個變量就會被Java虛擬機回收。而session變量。而request級別的Bean就應(yīng)該是JSP頁面的成員變量。而session和 application則不能在JSP頁面class里面保存,而應(yīng)該保存在JSP頁面的調(diào)用對象里面。
9.關(guān)于<%@ page %>命令,這個就太簡單了,只是一個一個的對應(yīng)為response.setContentType()的語句而已。
10.關(guān)于JSP頁面翻譯轉(zhuǎn)向問題。這個語句被翻譯為getServletContext().getRequestDispatcher("/List.jsp").forward(req, res);語句。
11.<%@ include file="included.jsp" %> 遇到這個語句,JSP翻譯器就會把這個文件的代碼和現(xiàn)在文件的代碼混合然后一起編譯,生成JSP類。這個方法很好,可以讓我們統(tǒng)一文檔的樣式,比如說吧 header寫成一個文件,,而把footer也寫成一個JSP ,并且在index.html里面把這兩個文件包含近來,這樣,不管Content怎么變,上下樣式都不會變,有利于樣式的統(tǒng)一。
以上是JSP頁面翻譯過程的簡單探討,更加詳細(xì)的細(xì)節(jié)可以參考tomcat的源代碼,了解這些原理對于學(xué)習(xí)JSP來說,是非常重要的,能大大的提高學(xué)習(xí)的效率。
【編輯推薦】