jsp技術總結

Jsp技術總結

1. 什么是JSP

? ? ? ? JSP即Java Server Pages,它和servlet技術一樣,都是sun公司定義的一種用于開發動態web資源的技術。該技術的最大特點在于:寫JSP就像寫html,但它相比html而言,html只能為用戶提供靜態數據,而JSP技術允許在頁面中嵌套java代碼,為用戶提供動態數據。

2. JSP原理

1) web服務器是如何調用并執行一個JSP頁面的?

? ? ? ? 服務器首先將JSP翻譯為一個Servlet,翻譯過后的Servlet可以在\tomcat主目錄\work\Catalina\localhost\工程名\org\apache\jsp目錄下查看,這是服務器的工作目錄。打開相應的Servlet可以看到,翻譯過后的servlet繼承了org.apache.jasper.runtime.HttpJspBase,而HttpJspBase繼承了HttpSerrvlet。說到這里,我們就明白了,其實JSP就是一個Servlet,訪問jsp即訪問一個Servlet。

2) JSP頁面中的html排版標簽是如何被發送到客戶端的以及java代碼服務器是如何執行的?

? ? ? ? 繼續瀏覽JSP翻譯過后的Servlet,里面有個service方法_jspService(request, response),在該方法中可以看到,JSP中的所有內容都會翻譯到service方法中,html代碼會通過out輸出,就像學習JSP之前,在Servlet中用out輸出html語句一樣,java部分代碼會原封不動的搬到service方法中。

3) web服務器在調用JSP時,會給JSP提供一些什么java對象?

? ? ? ? web服務器在將JSP翻譯成Servlet時,會在service方法中提供web開發所有的對象,這樣在JSP頁面中,我們就可以直接使用這些對象了,而不用再去獲得。web服務器所提供的對象(這些對象我們下面戶詳細分析)有:

[java] view plaincopy

final javax.servlet.jsp.PageContext pageContext;? ? ? ? //pageContext對象?

javax.servlet.http.HttpSession session = null;? ? ? ? ? //session對象?

final javax.servlet.ServletContext application;? ? ? ? ? //application對象?

final javax.servlet.ServletConfig config;? ? ? ? ? ? ? ? //config對象?

javax.servlet.jsp.JspWriter out = null;? ? ? ? ? ? ? ? ? //out對象?

final java.lang.Object page = this;? ? ? ? ? ? ? ? ? ? ? //page對象?

javax.servlet.jsp.JspWriter _jspx_out = null;? ? ? ? ? ? ?

javax.servlet.jsp.PageContext _jspx_page_context = null;?

? ? ? ? 還有service方法的參數request和response。所以Servlet可以做的事,JSP都可以做。但是兩者各有特點,我們繼續往下看。

3. JSP的最佳實踐

? ? ? ? 不管是JSP還是Servlet,雖然都可以用于開發動態web資源,但是由于這2門技術各自的特點,在長期的軟件實踐中,人們逐漸把servlet作為web應用中的控制器組件來使用,而把JSP技術作為數據顯示模板來使用。原因在于,程序的數據通常要美化后再輸出。讓JSP既用java代碼產生動態數據,又做美化會導致頁面難以維護;讓Servlet既產生數據,又在里面嵌套html代碼美化數據,同樣也會導致程序可讀性差,難以維護;因此最好的辦法就是讓Servlet負責相應請求產生的數據,并把數據通過轉發技術帶給JSP,JSP用來做數據的顯示。

4. JSP語法

1) JSP模板元素

? ? ? ? JSP模板元素即JSP頁面中的HTML內容。JSP模板元素定義了網頁的基本骨架,即定義了頁面的結構和外觀。

2) JSP腳本表達式

? ? ? ? JSP腳本表達式用于將程序數據輸出到客戶端。

? ? ? ? 語法:<%= 變量或表達式 %> 如:當前時間:<%= new java.util.Date() %>

? ? ? ? JSP引擎在翻譯腳本表達式時,會將程序數據轉成字符串,然后在相應位置用out.print(...)將數據輸給客戶端。

? ? ? ? 注意:JSP腳本表達式中的變量或表達式后面不能有分號(;)

3) JSP腳本片段

? ? ? ? JSP腳本片段用于在JSP頁面中編寫多行java代碼。

? ? ? ? 語法:<% 多行java代碼 %>

? ? ? ? 注意:JSP腳本片段只能出現java代碼,不能出現其他模板元素,JSP引擎在翻譯JSP頁面中,會將JSP腳本片段中的Java代碼原封不動的放到Servlet的_jspService方法中。JSP腳本片段中的java代碼必須嚴格遵循java語法。

? ? ? ? 在一個JSP頁面中可以有多個腳本片段,在兩個或多個腳本片段之間可以嵌入文本、HTML標記和其他JSP元素。不同腳本片段中的代碼可以相互訪問,猶如將所有的代碼放到一個<% %>中一樣。但是所有的腳本片段組合在一起必須是一個完整的java代碼。

4) JSP聲明

? ? ? ? JSP聲明中的java代碼會被翻譯到_jspService方法的外面。(面試題)

? ? ? ? 語法:<%! java代碼 %>

? ? ? ? 所以,JSP聲明可用于定義JSP頁面轉換成Servlet程序的靜態代碼塊、成員變量和方法。多個靜態代碼塊、變量和方法可以定義在一個JSP聲明中,也可以分別單獨定義在多個JSP聲明中。

? ? ? ? JSP隱式對象的作用范圍僅限于Servlet的_jspService方法中,而JSP聲明的代碼會被翻譯到該方法的外面,所以在JSP聲明中不能使用這些隱式對象。

5) JSP注釋

? ? ? 語法:<%- 注釋信息 -%>

? ? ? JSP引擎在將JSP頁面翻譯成Servlet時,忽略JSP頁面中被注釋的內容。

? ? ? ? 如果在JSP中使用<!-- 注釋內容-->時,注釋內容會打給瀏覽器,瀏覽器認識這個注釋,所以不會顯示給用戶。而JSP注釋將注釋內容不打給瀏覽器。

6) JSP指令

? ? ? ? JSP指令是為JSP引擎而設計的,它們并不直接產生任何可見輸出,而只是告訴引擎如何處理JSP頁面中其余的部分。

? ? ? ? 語法:<%@ 指令 屬性名="值" %>

? ? ? ? 如:<%@ page contentType="text/html;charset=UTF-8" %>? ? <%@ page import="java.util.Date" %>

? ? ? ? 如果一個指令有多個屬性,這多個屬性可以寫在一個指令中,中間用空格隔開。即上面兩條指令等價表示如下:? ? ?

[html] view plaincopy

<%@ page contentType="text/html;charset=UTF-8" import="java.util.Date" %>? ? ? ? ?

? ? ? ? 在JSP2.0規范中共定義了三個指令:

? ? ? ? 1)page指令:

? ? ? ? page指令用于定義JSP頁面的各種屬性,無論page指令出現在JSP頁面中的什么地方,它的作用都是整個JSP頁面。為了保持程序的可讀性,page指令最好放在整個JSP頁面的起始位置。?

? ? ? ? ? 語法:

[html] view plaincopy

<%@ page?

? ? ? ? ? ? ? [import="{package.class | package.*},..."]?

? ? ? ? ? ? ? [session="true | false"]?

? ? ? ? ? ? ? [errorPage=""relative_url]?

? ? ? ? ? ? ? [isErrorPage="true | false"]?

? ? ? ? ? ? ? [contentType="mimeType[;charset=characterSet]" | "text/html;charset=ISO-8859-1]?

? ? ? ? ? ? ? [pageEncoding="characterSet | ISO-8859-1"]?

? ? ? ? ? ? ? [isELIgnored="true | false"]?

%>? ?

? ? ? ? JSP引擎會自動導入如下包:java.lang.* / java.servlet.* / javax.servlet.jsp.* / javax.servlet.http.*

? ? ? ? JSP導入多個包的時候,可以分開寫,也可以放在一起寫,放在一起的時候,使用逗號分隔:? ? ? ?

[html] view plaincopy

<%@ paga import="java.util.Date,java.sql.*,java.io.*"%>? ? ?

? ? ? ? session屬性設置為true時,翻譯后的servlet中會自動創建session對象,false則不創建。

? ? ? ? errorPage屬性用來設置錯誤相應頁面。它的值必須使用相對路徑,如果以"/"開頭,表示相對于當前web應用程序的根目錄(注意不是站點根目錄),否則,表示相對于當前頁面。也可以在web.xml文件中使用<error-page>元素為整個web應用程序設置錯誤處理頁面,其中<exception-type>子元素指定異常類的完全限定名,<location>元素指定以"/"開頭的錯誤處理頁面路徑。如果設置了某個JSP頁面的errorPage屬性,那么在web.xml文件中設置的錯誤處理將不對該頁面起作用。

? ? ? ? isErrorPage為true時,表示該頁面是處理錯誤頁面,JSP引擎在翻譯成servlet時,會定義一個exception對象,從而就可以用exception隱式對象獲得出錯信息。

? ? ? ? JSP引擎會根據page指令的contentType屬性生成相應的調用ServletResponse.setContentType方法的語句。? ? ?

? ? ? ? 2) include指令:?

? ? ? ? include指令用于引入其他JSP頁面,如果使用include指令引入了其他JSP頁面,那么JSP引擎將把這兩個JSP翻譯成一個servlet,所以include指令引入通常稱為靜態引入。由于JSP引擎會把多個JSP頁面翻譯成一個Servlet,所以,在被引入的JSP中,全局架構的代碼可以去掉(<html><head><body>等)(當然這不是必須的),這樣避免與當前JSP頁面中的重復。

? ? ? 語法:

[html] view plaincopy

<% include file="relativeURL"%>?

? ? ? 其中file屬性用于指定被引入文件的路徑。以"/"開頭,表示代表當前web應用。

? ? ? 幾個細節需要注意:

? ? ? ? · 被引入的文件必須遵循JSP語法;

? ? ? ? · 被引入的文件可以使用任意的擴展名,即使擴展名為html,JSP引擎也會按照處理JSP頁面的方式去處理,為了見名知意,JSP規范建議使用.jspf(JSP fragments)作為靜態引入文件的擴展名;

? ? ? ? · 由于使用include指令將會涉及到2個JSP頁面,并會把2個JSP翻譯成一個Servlet,所以這兩個JSP頁面的指令不能沖突(除了pageEncoding和導包除外)。比如現在要引入兩個JSP頁面,一個JSP中session="true",另一個JSP中session="false",這樣在引入這兩個JSP頁面時就會產生沖突,服務器會報錯。

? ? ? 在JSP中也可以使用java代碼實現動態包含:?

[java] view plaincopy

<% request.getRequestDispather("relativeURL").include(request,response);%>?

? ? ? 這樣JSP引擎會將不同的JSP頁面翻譯成不同的Servlet,動態包含只是引入其他JSP頁面的結果。動態包含的時候,服務器會調用多個web資源,而靜態包含時,被翻譯成一個Servlet,服務器只需要調用一個web資源,所以靜態包含性能好一點,開發時用靜態包含。

? ? ? ? 3)taglib指令:用來導入自定義標簽庫,見后面自定義標簽部分的內容

5. JSP運行原理和9大隱式對象

? ? ? ? 由上文可知:每個JSP頁面在第一次被訪問時,web容器都會把請求交給JSP引擎(即一個java程序)去處理。JSP引擎現將JSP翻譯成一個_jspServlet(實質上也是一個Servlet),然后按照Servlet的調用方式進行調用。由于JSP第一次訪問時會翻譯成Servlet,所以第一次訪問通常會比較慢,但第二次訪問,JSP引擎如果發現JSP沒有變化,就不再翻譯,而是直接調用,所以程序的執行效率不會受到影響。

? ? ? ? JSP引擎在調用JSP對應的_jspServlet時,會傳遞或創建9個與web開發相關的對象供_jspServlet使用。JSP技術的設計者為便于開發人員在編寫JSP頁面時獲得這些web對象的引用,特意定義了9個相應的變量,開發人員在JSP頁面中通過這些變量就可以快速獲得這9大對象的引用,9大隱式對象是哪些以及各自的作用是什么?

[java] view plaincopy

request://就是Servlet里的request?

response: //就是Servlet里的response?

session: //就是Servlet里的session?

application: //就是servlet里的servletContext?

config: //就是Servlet里的servletConfig?

page: //就是Servlet自己?

exception: //異常,只有errorPage才有?

out://JSP頁面輸出?

pageContext:<span style="font-family:Microsoft YaHei;">//</span>pageContext對象是JSP技術中最重要的一個對象,它代表JSP頁面的運行環境?

? ? ? ? pageContext對象是JSP技術中最重要的一個對象,它代表JSP頁面的運行環境,這個對象不僅封裝了對其它8大隱式對象的引用,它自身還是一個域對象,可以用來保存數據。并且,這個對象還封裝了web開發中經常涉及到的一些常用操作,例如引入和跳轉其它資源、檢索其它域對象中的屬性等。

[java] view plaincopy

getException<span style="font-family:Microsoft YaHei;">()? //</span>方法返回exception隱式對象?

getPage<span style="font-family:Microsoft YaHei;">()? //</span>方法返回page隱式對象?

getRequest()? //方法返回request隱式對象?

getResponse()? //方法返回response隱式對象?

getgetServletContext()? //方法返回application隱式對象?

getServletConfig()? //方法返回config隱式對象?

getSession()? //方法返回session隱式對象?

getOut()? //方法返回out隱式對象?

pageContext作為一個域對象,還封裝了下面的方法:

[java] view plaincopy

//pageContext域對象的方法:?

public void setAttribute(String name, Object value)?

public Object getAttribute(String name)?

public void removeAttribute(String name)?

//pageContext對象中還封裝了訪問其它域的方法(重要)?

public void setAttribute(String name, Object value, int scope)?

public Object getAttribute(String name, int scope)?

public void removeAttribute(String name, int scope)?

//代表各個域的常量?

pageContext.APPLICATION_SCOPE?

pageContext.SESSION_SCOPE?

pageContext.REQUEST.SCOPE?

pageContext.PAGE_SCOPE?

? ? ? ? 到現在為止,應該可以看出pageContext對象的強大之處了!另外還有個findAttribute方法(*重要,查找各個域中的屬性,EL表達式就依賴于這個方法),可以直接調用pageContext.findAttribute(String name),首先會從pageContext里找該屬性,如果沒有,會依次按照下面順序在相應的域中查找:request, session, servletContext,如果沒找著,返回null,否則返回屬性值。

? ? ? ? pageContext類中定義了一個forward方法和兩個include方法分別簡化和替代RequestDispatcher.forward方法和include方法,方法接收的資源如果以"/"開頭,"/"代表當前web應用。不過這里的include是動態包含,不建議使用include。

6. JSP標簽

? ? ? ? JSP標簽也稱為JSP動作元素,它用于在JSP頁面中提供業務邏輯功能,避免在JSP頁面中直接編寫java代碼造成JSP頁面難以維護。JSP有三種標簽

1) <jsp:include>標簽

? ? ? ? <jsp:include>標簽用于把另外一個資源的輸出內容插入進當前JSP頁面的輸出內容之中,這種在JSP頁面執行時的引入方式稱為動態引入。

? ? ? ? 語法:

[html] view plaincopy

<jsp:include page="relativeURL | <%= expression%>" flush="true | false" />?

? ? ? ? 相當于調用pageContext.include("relativeURL")

? ? ? ? page屬性用于指定被引入資源的相對路徑,它也可以通過執行一個表達式來獲得。flush屬性指定在插入其他資源的輸出內容時,是否先將當前JSP頁面都已輸出的內容刷新到客戶端。

2) <jsp:forward>標簽

? ? ? ? <jsp:forward>標簽用于把請求轉發給另一個資源

? ? ? ? 語法:

[html] view plaincopy

<jsp:forward page="relativeURL | <%= expression%>" />?

? ? ? ? page屬性用于指定請求轉發到的資源的相對路徑,它可以通過執行一個表達式來獲得。

3) <jsp:param>標簽

? ? ? ? 當使用<jsp:include>和<jsp:forward>標簽引入或將請求轉發給其它資源時,可以使用<jsp:param>標簽向這個資源傳遞參數。

? ? ? ? 語法1:

[html] view plaincopy

<jsp:include page="relativeURL | <%=expression%>">?

? ? ? <jsp:param name="parameterName" value="parameterValue | <%=expression%>" />?

</jsp:include>?

? ? ? ? 相當于relativeURL?name=...&value=....

? ? ? ? 語法2:

[html] view plaincopy

<jsp:forward page="relativeURL | <%=exception%>">?

? ? ? <jsp:param name="parameterName" value="parameterValue | <%=expression%>" />?

</jsp:forward>?

? ? ? ? 相當于relativeURL?name=...&value=....

? ? ? ? <jsp:param>標簽的name屬性用于指定參數名,value屬性用于指定參數值。在<jsp:include>和<jsp:forward>標簽中可以使用多個<jsp:param>標簽來傳遞多個參數。

7. JSP映射

? ? ? ? JSP也可以像Servlet那樣映射,因為JSP本來就是Servlet。

[html] view plaincopy

<servlet>?

? ? <servlet-name>SimpleJspServlet</servlet-name>?

? ? <jsp-file>/jsp/simple.jsp</jsp-file>?

</servlet>?

?

<servlet-mapping>?

? ? <servlet-name>SimpleJspServlet</servlet-name>?

? ? <url-pattern>/xxx/yyy.html</url-pattern>?

</servlet-mapping>?

? ? ? ? /jsp/simple.jsp表示在webRoot/jsp目錄下的simple.jsp文件

8. 四個域對象

? ? ? ? 到目前為止,web開發共接觸到了4個域對象,這4個域對象是學習web的重點,也是筆試經常考察的知識點:

[java] view plaincopy

pageContext(稱為page域): //pageContext中存的數據在頁面范圍都可以取出?

request(稱為request域):? //request中存的數據在請求范圍內都可以取出?

session(稱為session域):? //session中存的數據在會話范圍內都可以取出?

servletContext(稱為application域)://servletContext中存的數據在整個應用程序范圍內都可以取出?

? ? ? ? 明確如下兩個問題:這四個對象的生命周期?哪種情況下用哪種對象?

? ? ? ? request:如果客戶機向服務器發請求產生的數據,用戶看完就沒用了,向這樣的數據就存在request域中。如用戶看的新聞。

? ? ? ? session:如果客戶機向服務器發請求產生的數據,用戶用完了等一會兒還有用,向這樣的數據就存在session域中。如用戶購買的東西,因為結賬還要用到。

? ? ? ? servletContext:如果客戶機向服務器發請求產生的數據,用戶用完了還要給其他用戶用,向這樣的數據就存在servletContext域中。如聊天室中說出的話,因為話要在自己頁面中看到,別人也要看到。

? ? ? ? 實際中,能用小的容器就不要用大的,即request能滿足就不要用session,session能滿足就不要用servletContext

9. 總結

? ? ? ? 由于JSP一般都是通過servlet轉發過來,servlet會通過容器將數據帶過來,所以會使用JSP從容器中取出數據然后顯示出來即可。取數據用腳本片段<%%>來取,顯示用腳本表達式<%= %>處理。在學習了EL表達式和自定義標簽后,腳本片段就可以用自定義標簽替代,腳本表達式就可以用EL表達式替代了。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容

  • 1.學習內容 JSP技術入門和常用指令 JSP的內置對象&標簽介紹 EL表達式&EL的內置對象 2.JSP技術入門...
    WendyVIV閱讀 2,159評論 1 18
  • 1.什么是JSP (1)jsp全稱是Java Server Pages,它和Servlet技術一樣都是sun公司定...
    yjaal閱讀 3,676評論 5 99
  • 一、JSP基礎 1.1什么是JSP JSP(Java ServerPage)是Java服務器端動態頁面技術。是su...
    晨星資源閱讀 1,165評論 0 6
  • 這部分主要是與Java Web和Web Service相關的面試題。 96、闡述Servlet和CGI的區別? 答...
    雜貨鋪老板閱讀 1,421評論 0 10
  • 6月18號,星期天,今天是父親節。 拿起電話拔了遠在家鄉父親的電話。“喂,是錦成嗎。”電話那頭傳來慈祥熟悉的聲音。...
    狩望_佛山閱讀 326評論 9 13