1. 程式人生 > 其它 >Web基礎知識(9)- JSP (一)

Web基礎知識(9)- JSP (一)

JSP 簡介、JSP 生命週期、JSP 程式、JSP 語法

 

1. JSP 簡介

    JSP(Java Server Pages)是一種動態網頁開發技術。JSP 檔案就是在傳統的 HTML 檔案中插入 Java 程式碼和 JSP 標籤,字尾名為.jsp,程式碼標籤 <% %>。

    JSP 是 Servlet 的擴充套件,我們可以在 JSP 中使用 Servlet 的所有功能。另外,JSP 還提供了一些其他功能,例如 EL 表示式、自定義標籤等。

    JSP 依賴於 Servlet,使用者訪問 JSP 頁面時,JSP 程式碼會被翻譯成 Servlet 程式碼,最終,以字串的形式向外輸出 HTML 程式碼。所以,JSP 只是在 Servlet 的基礎上做了進一步封裝。

    1) JSP 的由來

        1997 年,Sun 公司推出了 Servlet。

        由於當時的 Java Web 層體系結構中只有 Servlet,所以接收使用者請求、處理業務邏輯、生成 HTML 程式碼等都在 Servlet 中完成。Servlet 不能像 PHP、ASP 等語言鑲嵌 HTML 程式碼,因此輸出 HTML 比較困難,且部署過程複雜。

        為了克服 Servlet 的這些弱點,1999 年初,Sun 公司推出了 JSP。在生成 HTML 程式碼方面 JSP 比 Servlet 方便許多,而且不需要特殊部署,只需要複製到伺服器下面即可執行。簡而言之,JSP 就是為了簡化 Servlet 工作而出現的替代品。

        JSP 包括很多技術,包括 Java Bean、自定義標籤(Custom Tags)、EL 表示式(Expression Language)、JSTL 標準標籤類庫(Java Standard Tag Library)等。這些強大成熟的技術使得 JSP 在檢視層(View)具有很大的優勢。

    2) JSP 具有以下特點

        (1) JSP 具有 Servlet 的所有優點,例如 JSP 檔案跨平臺,即一次編寫,處處執行;
        (2) JSP 比 Servlet 更易於維護,JSP 將業務邏輯與網頁設計分離,Web 開發人員可以更注重於網頁設計,Java 開發人員可以更注重於邏輯處理;
        (3) JSP 基於Java Servlets API,JSP擁有各種強大的企業級 Java API,包括 JDBC,JNDI,EJB,JAXP 等等;
        (4) JSP 頁面可以與處理業務邏輯的 Servlet 一起使用,這種模式被 Java Servlet 模板引擎所支援;
        (5) JSP 是Java EE不可或缺的一部分,是一個完整的企業級應用平臺。這意味著 JSP 可以用最簡單的方式來實現最複雜的應用。

 

2. JSP 生命週期

    JSP 生命週期定義了 JSP 從建立到銷燬的整個過程。這類似於 Servlet 生命週期,不同的是,JSP 需要先被編譯成 Servlet。

    JSP 生命週期階段如下:

        編譯 -> 初始化 -> 執行 -> 銷燬

    1) JSP 編譯

        當瀏覽器請求 JSP 時,JSP 容器會首先檢查是否需要編譯頁面。如果該頁面從未被編譯過,或者自上次編譯以來對其進行了修改,則編譯該頁面。

        JSP 本質是 Servlet,因此 JSP 容器就是 Servlet 容器。

        編譯過程包括 3 個步驟:

            (1) 解析 JSP:JSP 容器解析 JSP 檔案,檢視是否有語法錯誤;
            (2) 翻譯 JSP:JSP 容器把 JSP 檔案翻譯為 Servlet 類;
            (3) 編譯 Servlet;

    2) JSP 初始化

        當容器載入 JSP 時,它將在處理任何請求之前呼叫 jspInit() 方法。如果您需要自定義 JSP 的初始化內容,可以重寫 jspInit() 方法。

            public void jspInit(){
                //
            }

        一般情況下,程式只初始化一次。與 Servlet init 方法一樣,我們通常在 jspInit() 方法中初始化資料庫連線、開啟檔案。

    3) JSP 執行

        此階段表示了 JSP 生命週期中所有與請求相關的互動行為,直到被銷燬。

        JSP 頁面完成初始化後,JSP 將會呼叫 _jspService() 方法。

        _jspService() 以 HttpServletRequest 物件和 HttpServletResponse 物件作為方法引數,如下所示:

            void _jspService(HttpServletRequest request, HttpServletResponse response) {
                //
            }

        JSP 的 _jspService() 方法根據 request 來生成相應的 response,並且它還負責生成對 HTTP 方法的響應,即 GET、POST、DELETE 等。

    4) JSP 銷燬

        JSP 生命週期的銷燬階段表示從容器中刪除 JSP。

        jspDestroy() 方法等效於 Servlet 中的 destroy() 方法。如果您需要自定義 JSP 的銷燬內容,可以重寫,格式如下:

            public void jspDestroy() {
                //
            }

        通常我們在 jspDestroy() 方法中釋放資料庫連線、關閉開啟的檔案。 


3. JSP 程式

    在 “Web基礎知識(2)- Java Servlet (二)”  裡 IDEA 建立的 Maven Webapp 專案中,自動建立了 src/main/webapp/index.jsp,內容如下:

        <html>
        <body>
        <h2>Hello World!</h2>
        </body>
        </html>

    這個 index.jsp 是沒有 JSP 標籤一個 HTML 檔案,修改如下:

 1         <%@ page contentType="text/html;charset=UTF-8" language="java"%>
 2         <%@ page import="java.util.Date, java.text.SimpleDateFormat" %>
 3         <html>
 4         <head>
 5             <title>Index</title>
 6         </head>
 7         <body>
 8             <%-- JSP 宣告語句 --%>
 9             <%!
10                 // 重寫 jspInit()
11                 public void jspInit(){
12                     super.jspInit();
13                     System.out.println("JSP init()");
14                 }
15 
16                 // 重寫 jspDestroy()
17                 public void jspDestroy() {
18                     super.jspDestroy();
19                     System.out.println("JSP destroy()");
20                 }
21             %>
22 
23             <%-- JSP 指令碼 --%>
24             <!-- Header Title -->
25             <h3><% out.print("Index Page"); %></h3>
26 
27             <%!
28                 // JSP 宣告語句
29                 private int a=11;
30                 private int getNum(int a,int b){
31                     return a+b;
32                 }
33             %>
34 
35             <%-- JSP 表示式 --%>
36             <p>getNum(3,5) 的返回值:<%=getNum(3,5)%></p>
37 
38             <%
39                 Date date = new Date();
40                 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
41                 String nowTime = dateFormat.format(date);
42             %>
43             <%-- 獲取當前時間 --%>
44             <p>當前時間為:<%=nowTime %></p>
45 
46         </body>
47         </html>


    程式碼解釋:

        <%@ page contentType="text/html;charset=UTF-8" language="java"%> 指定該網頁型別為 "text/html,網頁字元編碼為 UTF-8,language="java" 指定該網頁程式語言為 Java。

        <%@ page import="java.util.Date, java.text.SimpleDateFormat" %> 類似於Servlet 中 import 類。

        <head>、<title> 和 <body> 都是 HTML 標籤,用於靜態網頁,他們包含的內容都將直接傳遞給客戶端,也就是 Web 瀏覽器。

        <%! %> 是 JSP 宣告語句,用於宣告一個或多個變數、方法,以供後面的 Java 程式碼使用。

        <% out.print("Index Page"); %> 是 JSP 指令碼,等價於 <%="Index Page" %>。

        <%= %> 是 JSP 表示式,用於列印變數和方法的返回值。

        <%-- --%> 是隱藏註釋,在瀏覽器的原始碼裡無法看到它。

        <!-- --> 是HMTL註釋,在瀏覽器的原始碼裡可以看到它。


4. JSP 語法


    1) JSP 指令碼

        在 JSP 中,可以使用 JSP 指令碼寫入 Java 程式碼。

        JSP 指令碼可以包含任意數量的 Java 語句,變數、方法和表示式。JSP 指令碼會把包含的內容插入到 Servlet 的 service() 方法中。

        JSP 指令碼語法如下:

            <% Java語句 %>

        等效於

            <jsp:scriptlet>
                Java語句
            </jsp:scriptlet>

        任何文字、HTML 標籤和 JSP 元素(宣告,表示式等)都必須在指令碼程式之外。

    2) JSP 宣告語句

        JSP 宣告語句用於宣告一個或多個變數、方法,以供後面的 Java 程式碼使用。您必須先對變數和方法進行宣告,才能使用它們。

        JSP 宣告語法如下:

            <%! 宣告語句 %>

        等效於

            <jsp:declaration>
                宣告語句
            </jsp:declaration>

        示例

            <%! int num = 0; %>
            <%! Circle a = new Circle(2.0); %>
            <%!
                public void show () {
                }
            %>
            
        JSP 指令碼和宣告的區別:

            (1) JSP 指令碼只能宣告變數,不能宣告方法。JSP 宣告語句可以宣告變數和方法。
            (2) JSP 指令碼會把包含的內容轉譯插入到 Servlet 的 service() 方法中,也就是 <% %> 中定義的變數是區域性變數。這也是 JSP 指令碼不能宣告方法的原因,因為 Java 不允許方法中巢狀方法。
            (3) JSP 宣告會把包含的內容新增到 Servlet 類中(在任何方法之外),也就是 <%! %> 中定義的變數是成員變數,方法是成員方法。

    3) JSP 表示式

        JSP 表示式可以把變數或者表示式輸出到網頁上,不需要 out.print() 就能輸出資料。

        JSP 表示式語法如下:

            <%= 表示式 %>

        等效於

            <jsp:expression>
                表示式
            </jsp:expression>
        
        可以將 <%=表示式 %> 理解為 <% out.println(表示式) %> 的簡寫方式。這裡需要注意,JSP 表示式不能以分號結尾。

    4) JSP 註釋

        註釋可以提高程式碼的可讀性,讓他人能夠更加輕鬆地瞭解程式碼,從而提高團隊合作開發的效率。

        (1) HTML 註釋

            由於 JSP 檔案中可以包含 HTML 標記,所以 HTML 中的註釋同樣可以在 JSP 檔案中使用。HTML 註釋語法如下:

                <!-- 註釋內容 -->

            HTML 註釋中的內容是不會在客戶端瀏覽器中顯示的,但可以通過 HTML 原始碼看到這些註釋內容。

        (2) 帶有 JSP 表示式的註釋

            在 HTML 註釋中還可以嵌入 JSP 表示式,格式如下:

                <!--HTML 註釋內容<%=JSP 表示式%>-->

            包含該註釋語句的 JSP 頁面被請求後,伺服器能夠自動識別並執行註釋中的 JSP 表示式,對於註釋中的其他內容則不做任何操作。

            當伺服器將執行結果返回給客戶端瀏覽器後,註釋的內容也不會在瀏覽器中顯示。

            當我們檢視 HTML 原始碼時,只能檢視到 JSP 表示式執行後的結果,並不能看到原來的 JSP 表示式。
            
            示例:

                <% String name = "admin"; %>
                <!--當前登入使用者為:<%=name%>-->
                <h1>歡迎您的到來,<%=name %></h1>

                訪問該 JSP 頁面,客戶端瀏覽器中會輸出以下內容:
                
                    歡迎您的到來,admin

        (3) 隱藏註釋

            無論是普通的 HTML 註釋還是帶有 JSP 表示式的註釋,雖然都不能在客戶端瀏覽器中顯示,但是它們卻都存在於 HTML 原始碼中,客戶端可以通過 HTML 原始碼看到被註釋的內容,所以嚴格來說,這兩種註釋其實並不安全。

            隱藏註釋的內容,不會顯示在客戶端的任何位置(包括 HTML 原始碼),安全性較高,其註釋格式如下:

                <%-- 註釋內容 --%>

            示例:

                <%
                    Date date = new Date();
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String nowTime = dateFormat.format(date);
                %>
                <%--獲取當前時間 --%>
                <h1>當前時間為:<%=nowTime %></h1>

                訪問該 JSP 頁面,客戶端瀏覽器中會輸出以下內容:

                    當前時間為:2021-06-17 10:46:29

        (4) JSP 指令碼(Scriptlet)中的註釋

            指令碼程式中包含的是一段 Java 程式碼,所以在指令碼程式中的註釋與在 Java 中的註釋是相同的。

            a) 單行註釋

                單行註釋的格式如下:
                
                    // 註釋內容

                符號 “//” 後面的內容為註釋的內容,伺服器對該內容不進行任何操作。由於指令碼程式的程式碼在客戶端通過檢視原始碼是不可見的,因此在指令碼程式中通過該方法註釋的內容也是不可見的。

                示例:

                    <%
                        int count=6;    // 定義一個計數變數
                    %>
                    計數變數 count:<%=count%>

                    訪問該 JSP 頁面,客戶端瀏覽器中會輸出以下內容:

                        計數變數 count:6

            b) 多行註釋

                多行註釋是通過 “/* ... */” 符號進行標記的,它們必須成對出現,在它們之間的註釋內容可以換行。註釋格式如下:
                    
                    /*
                        註釋內容1
                        註釋內容2
                    */

                與單行註釋一樣,在 “/* ... */” 之間註釋的所有內容,伺服器都不會做任何處理,即使被註釋的內容是 JSP 表示式或其他指令碼程式也不例外。

                多行註釋的開始標記和結束標記可以不在同一個指令碼程式中同時出現。

                示例:

                    <%
                        String name = "www.test.com";
                        /* if ("www.test.com".equals(name)) { %>
                            <h1>JSP 示例</h1>
                    <% }
                        */%>
                    <h1><%=name %></h1>

                    訪問該 JSP 頁面,客戶端瀏覽器中會輸出以下內容:

                        www.test.com  

            c) 文件註釋

                文件註釋的內容會被 Javadoc 文件工具在生成文件時讀取,文件是對程式碼結構和功能的描述。註釋格式如下:

                    /**
                        提示資訊1
                        提示資訊2
                    */

                文件註釋與多行註釋很相似,但它是以“/**”符號作為其開始標記的,而不是“/*”。與多行註釋一樣,被註釋的所有內容,伺服器不會做任何處理。

                示例:
                
                    <%!
                        /**
                            @作者:WebBasic
                            @網址:www.test.com
                        */
                        public String sayHello(String who) {
                            return "您好:" + who;
                        } %>
                    <h1><% out.println(sayHello("WebBasic")); %></h1>

                    訪問該 JSP 頁面,客戶端瀏覽器中會輸出以下內容:

                        您好:WebBasic