JavaWeb(六)JSP-1

1、JSP起源

(1)在很多動態網頁中,絕大部分內容都是固定不變的,只有局部內容需要動態產生和改變。

(2)如果使用Servlet程序來輸出只有局部內容需要動態改變的網頁,其中所有的靜態內容也需要程序員用Java程序代碼產生,整個Servlet程序的代碼將非常臃腫,編寫和維護都將非常困難。 

(3)對大量靜態內容的美工設計和相關HTML語句的編寫,並不是程序員所要做的工作,程序員對此也不一定在行。網頁美工設計和製作人員不懂Java編程,更是無法來完成這樣的工作。

(4)爲了彌補 Servlet 的缺陷,SUN公司在Servlet的基礎上推出了JSP(Java Server Pages)技術作爲解決方案。

(5)JSP是簡化Servlet編寫的一種技術,它將Java代碼和HTML語句混合在同一個文件中編寫,只對網頁中的要動態產生的內容採用Java代碼來編寫,而對固定不變的靜態內容採用普通靜態HTML頁面的方式編寫。

2、建立對JSP的直觀認識

(1)JSP頁面是由HTML語句和嵌套在其中的Java代碼組成的一個普通文本文件,JSP 頁面的文件擴展名必須爲.jsp。

(2)在JSP頁面中編寫的Java代碼需要嵌套在<%和%>中,嵌套在<%和%>之間的Java代碼被稱之爲腳本片段(Scriptlets),沒有嵌套在<%和%>之間的內容被稱之爲JSP的模版元素。

(3)JSP中的Java代碼可以使用out.println語句將其他Java程序代碼產生的結果字符串輸出給客戶端,也可以使用System.out.println語句將它們打印到命令行窗口。

(4)JSP文件就像普通的HTML文件一樣,它們可以放置在WEB應用程序中的除了WEB-INF及其子目錄外的其他任何目錄中,JSP頁面的訪問路徑與普通HTML頁面的訪問路徑形式也完全一樣。

(5)在JSP頁面中也可以使用一種稱之爲JSP表達式的元素,只需將要輸出的變量或表達式直接封裝在<%= 和 %>之中,就可以向客戶端輸出這個變量或表達式的運算結果。在JSP表達式中嵌套的變量或表達式後面不能有分號。

3、JSP的運行原理

(1)WEB容器(Servlet引擎)接收到以.jsp爲擴展名的URL的訪問請求時,它將把該訪問請求交給JSP引擎去處理。

(2)每個JSP 頁面在第一次被訪問時,JSP引擎將它翻譯成一個Servlet源程序,接着再把這個Servlet源程序編譯成Servlet的class類文件,然後再由WEB容器(Servlet引擎)像調用普通Servlet程序一樣的方式來裝載和解釋執行這個由JSP頁面翻譯成的Servlet程序。

(3)JSP規範也沒有明確要求JSP中的腳本程序代碼必須採用Java語言,JSP中的腳本程序代碼可以採用Java語言之外的其他腳本語言來編寫,但是,JSP頁面最終必須轉換成Java Servlet程序。

(4)可以在WEB應用程序正式發佈之前,將其中的所有JSP頁面預先編譯成Servlet程序。

4、實例

(1)新建一個hello.jsp


(2)編譯成Servlet程序


(3)查看hello_jsp.java




(4)在eclipse按Ctrl+T查看HttpJspBase類,從該類可以看出,它也繼承了HttpServlet

public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {    private static final long serialVersionUID = 1L;        protected HttpJspBase() {    }        @Override    public final void init(ServletConfig config)   throws ServletException    {        super.init(config);        jspInit();        _jspInit();    }    @Override    public String getServletInfo() {        return Localizer.getMessage("jsp.engine.info");    }    @Override    public final void destroy() {        jspDestroy();        _jspDestroy();    }    @Override    public final void service(HttpServletRequest request, HttpServletResponse response)        throws ServletException, IOException    {        _jspService(request, response);    }    @Override    public void jspInit() {    }    public void _jspInit() {    }    @Override    public void jspDestroy() {    }    protected void _jspDestroy() {    }    @Override    public abstract void _jspService(HttpServletRequest request, HttpServletResponse response)        throws ServletException, IOException;}
​5、JSP隱式對象

JSP 頁面的隱含變量:沒有聲明就可以使用的對象.,JSP頁面一共有 9 個隱含對象。

使用 <% %> 編寫的代碼在此位置,可以用到 request,response, pageContext,session,application,config,out,page 這 8 個隱含對象。 (實際上還可以使用一個叫 exception 的隱含對象)

①. request: HttpServletRequest 的一個對象。

②. response: HttpServletResponse 的一個對象(在 JSP 頁面中幾乎不會調用 response 的任何方法.)

③. pageContext: 頁面的上下文, 是 PageContext 的一個對象. 可以從該對象中獲取到其他 8 個隱含對象. 也可以從中獲取到當前頁面的其他信息. (學習自定義標籤時使用它) 

④. session: 代表瀏覽器和服務器的一次會話, 是 HttpSession 的一個對象. 後面詳細學習. 

⑤. application: 代表當前 WEB 應用. 是 ServletContext 對象. 

⑥. config: 當前 JSP 對應的 Servlet 的 ServletConfig 對象(幾乎不使用). 若需要訪問當前 JSP 配置的初始化參數, 需要通過映射的地址纔可以.映射JSP

⑦. out: JspWriter 對象. 調用 out.println() 可以直接把字符串打印到瀏覽器上. 

⑧. page: 指向當前 JSP 對應的 Servlet 對象的引用, 但爲 Object 類型, 只能調用 Object 類的方法(幾乎不使用) 

⑨. exception: 在聲明瞭 page 指令的 isErrorPage="true" 時, 纔可以使用. *<%@ page isErrorPage="true" %>




6、JSP與Servlet的應用比較

(1)JSP是一種以產生網頁顯示內容爲中心的WEB開發技術,它可以直接使用模版元素來產生網頁文檔的內容。

(2)JSP頁面的源文件要比Servlet源文件簡單,並且JSP頁面的開發過程要比Servlet的開發過程簡單得多。

(3)JSP引擎可以對JSP頁面的修改進行檢測,並自動重新翻譯和編譯修改過的JSP文件。

(4)JSP技術是建立在Servlet技術基礎之上的,所有的JSP頁面最終都要被轉換成Servlet來運行。

(4)在大型WEB應用程序的開發中,Servlet與JSP經常要混合使用,各司其職,Servlet通常用作控制組件,並處理一些複雜的後臺業務,JSP則作爲顯示組件。

(5)一次響應過程可以劃分成幾個功能模塊來協同完成,首先由Servlet完成流程控制和業務處理,並將結果數據存儲在request或session域中,然後將請求轉發(forward)到JSP頁面,再由JSP頁面從request或session域中取出結果數據並完成響應內容的輸出。通過這種方式實現業務邏輯與顯示內容的分離,從而將應用程序開發者和網頁作者的工作分離。

7、JSP基本語法

7.1、JSP模版元素

(1)JSP頁面中的靜態HTML內容稱之爲JSP模版元素,在靜態的HTML內容之中可以嵌套JSP的其他各種元素來產生動態內容和執行業務邏輯。

(2)JSP模版元素定義了網頁的基本骨架,即定義了頁面的結構和外觀。

7.2、JSP表達式

JSP表達式(expression)提供了將一個java變量或表達式的計算結果輸出到客戶端的簡化方式,它將要輸出的變量或表達式直接封裝在<%= 和 %>之中。

舉例:Current time: <%= new java.util.Date() %>

(1)JSP表達式中的變量或表達式的計算結果將被轉換成一個字符串,然後被插入進整個JSP頁面輸出結果的相應位置處。

(2)JSP表達式中的變量或表達式後面不能有分號(;),JSP表達式被翻譯成Servlet程序中的一條out.print(…)語句。

7.3、JSP腳本片斷

(1)JSP腳本片斷(scriptlet)是指嵌套在<% 和 %>之中的一條或多條Java程序代碼。

(2)在JSP腳本片斷中,可以定義變量、執行基本的程序運算、調用其他Java類、訪問數據庫、訪問文件系統等普通Java程序所能實現的功能。

(3)在JSP腳本片斷可以直接使用JSP提供的隱式對象來完成WEB應用程序特有的功能。

(4)JSP腳本片斷中的Java代碼將被原封不動地搬移進由JSP頁面所翻譯成的Servlet的_jspService方法中,所以,JSP腳本片斷之中只能是符合Java語法要求的程序代碼,除此之外的任何文本、HTML標記、其他JSP元素都必須在腳本片斷之外編寫。

(5)JSP腳本片斷中的Java代碼必須嚴格遵循Java語法,例如,每條命令執行語句後面必須用分號(;)結束。

(6)在一個JSP頁面中可以有多個腳本片斷(每個腳本片斷代碼嵌套在各自獨立的一對<% 和 %>之間),在兩個或多個腳本片斷之間可以嵌入文本、HTML標記和其他JSP元素,多個腳本片斷中的代碼可以相互訪問。

(7)單個腳本片斷中的Java語句可以是不完整的,但是,多個腳本片斷組合後的結果必須是完整的Java語句。


7.4、JSP聲明

(1)JSP聲明將Java代碼封裝在<%!和 %>之中,它裏面的代碼將被插入進Servlet的_jspService方法的外面,所以,JSP聲明可用於定義JSP頁面轉換成的Servlet程序的靜態代碼塊、成員變量和方法 。

(2)多個靜態代碼塊、變量和函數可以定義在一個JSP聲明中,也可以分別單獨定義在多個JSP聲明中。

(3)JSP隱式對象的作用範圍僅限於Servlet的_jspService方法,所以在JSP聲明中不能使用這些隱式對象。


7.5、JSP註釋

<%-- JSP 註釋 --%>

區別: JSP 註釋可以阻止 Java 代碼的執行,而HTML註釋不可以.


8、和屬性相關的方法

1). 方法

void setAttribute(String name, Object o): 設置屬性 

Object getAttribute(String name): 獲取指定的屬性

Enumeration getAttributeNames(): 獲取所有的屬性的名字組成的 Enumeration 對象

removeAttribute(String name): 移除指定的屬性

2). pageContext, request, session, application 對象都有這些方法!

這四個對象也稱之爲域對象.

pageContext: 屬性的作用範圍僅限於當前 JSP 頁面

request:  屬性的作用範圍僅限於同一個請求.

session: 屬性的作用範圍限於一次會話: 瀏覽器打開直到關閉稱之爲一次會話(在此期間會話不失效)

application: 屬性的作用範圍限於當前 WEB 應用. 是範圍最大的屬性作用範圍, 只要在一處設置屬性, 在其他各處的 JSP 或 Servlet 中都可以獲取到.

attr_1.jsp


attr2.jsp




關閉瀏覽器後,再次訪問attr_2.jsp,session的屬性值消失


9、請求的轉發和重定向

9.1、RequestDispatcher接口

(1)RequestDispatcher實例對象是由Servlet引擎創建的,它用於包裝一個要被其他資源調用的資源(例如,Servlet、HTML文件、JSP文件等),並可以通過其中的方法將客戶端的請求轉發給所包裝的資源。

(2)RequestDispatcher接口中定義了兩個方法:forward方法和include方法。

(3)forward和include方法接收的兩個參數必須是傳遞給當前Servlet的service方法的那兩個ServletRequest和ServletResponse對象,或者是對它們進行了包裝的ServletRequestWrapper 或ServletResponseWrapper對象。

(4)獲取RequestDispatcher對象的方法:

ServletContext.getRequestDispatcher (參數只能是以“/”開頭的路徑)

ServletContext.getNamedDispatcher

ServletRequest.getRequestDispatcher (參數可以是不以“/”開頭的路徑)

9.2、用sendRedirect方法實現請求重定向

(1)sendRedirect 方法不僅可以重定向到當前應用程序中的其他資源,它還可以重定向到同一個站點上的其他應用程序中的資源,甚至是使用絕對URL重定向到其他站點的資源。

(2)如果傳遞給sendRedirect 方法的相對URL以“/”開頭,則是相對於整個WEB站點的根目錄,而不是相對於當前WEB應用程序的根目錄。

9.3、請求重定向與請求轉發的比較

(1)RequestDispatcher.forward方法只能將請求轉發給同一個WEB應用中的組件;而HttpServletResponse.sendRedirect 方法還可以重定向到同一個站點上的其他應用程序中的資源,甚至是使用絕對URL重定向到其他站點的資源。

(2)如果傳遞給HttpServletResponse.sendRedirect 方法的相對URL以“/”開頭,它是相對於整個WEB站點的根目錄;如果創建RequestDispatcher對象時指定的相對URL以“/”開頭,它是相對於當前WEB應用程序的根目錄。

(3)調用HttpServletResponse.sendRedirect方法重定向的訪問過程結束後,瀏覽器地址欄中顯示的URL會發生改變,由初始的URL地址變成重定向的目標URL;調用RequestDispatcher.forward 方法的請求轉發過程結束後,瀏覽器地址欄保持初始的URL地址不變。

(4)HttpServletResponse.sendRedirect方法對瀏覽器的請求直接作出響應,響應的結果就是告訴瀏覽器去重新發出對另外一個URL的訪問請求;RequestDispatcher.forward方法在服務器端內部將請求轉發給另外一個資源,瀏覽器只知道發出了請求並得到了響應結果,並不知道在服務器程序內部發生了轉發行爲。

(5)RequestDispatcher.forward方法的調用者與被調用者之間共享相同的request對象和response對象,它們屬於同一個訪問請求和響應過程;而HttpServletResponse.sendRedirect方法調用者與被調用者使用各自的request對象和response對象,它們屬於兩個獨立的訪問請求和響應過程。

示例:








示例2:










本質區別: 請求的轉發只發出了一次請求, 而重定向則發出了兩次請求.

關注公衆號:Java後端生活,乾貨文章第一時間送達!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章