天天看點

javaweb簡單源代碼_Java Web輕松學39 - JSP核心原理目錄介紹Servlet要生成HTMLJSP核心原理JSP基本文法JSP其他技術這樣更好了解總結

本系列文章旨在記錄和總結自己在Java Web開發之路上的知識點、經驗、問題和思考,希望能幫助更多(Java)碼農和想成為(Java)碼農的人。
           

目錄

  1. 介紹
  2. Servlet要生成HTML
  3. JSP核心原理
  4. JSP基本文法
  5. 這樣更好了解
  6. 總結

介紹

前面的文章使用Servlet技術實作了一個簡單的租房網平台。

但是,它有很多不足,最直覺的感受應該就是:

  • 在Java代碼裡輸出HTML代碼實在是太難看、太繁瑣、太容易出錯了;
  • 如果想改變一下HTML呈現效果就必須修改HTML代碼,是以還必須重新編譯Java代碼。

是以,JSP技術應運而生了。

JSP的全稱是JavaServer Page,截止到目前最新版本好像是2.3,但在JCP官網(https://jcp.org/en/home/index)又隻能搜到2.1版本(關于JCP上如何下載下傳規範可以參考這篇文章)。如果有讀者知道如何下載下傳JSP 2.3版本的規範(或者沒有),請告知一下。

Servlet要生成HTML

對于Web應用來說,HTML頁面往往很重要,數量也比較多,每個頁面中的HTML代碼也比較多。

而動态生成的HTML頁面也是如此,大部分展示結構/效果/元素都是相同的,僅僅隻是資料不一樣。

javaweb簡單源代碼_Java Web輕松學39 - JSP核心原理目錄介紹Servlet要生成HTMLJSP核心原理JSP基本文法JSP其他技術這樣更好了解總結

可以這麼說,Servlet代碼中大部分是HTML代碼。

是以,我們是否能夠運用逆向思維:在HTML頁面中通過某種文法嵌入少量的Java代碼,然後讓工具自動生成Servlet的代碼?

JSP核心原理

答案當然是可行的,JSP正是這樣的技術。

javaweb簡單源代碼_Java Web輕松學39 - JSP核心原理目錄介紹Servlet要生成HTMLJSP核心原理JSP基本文法JSP其他技術這樣更好了解總結

這種在HTML頁面中嵌入Java代碼的頁面就叫JSP頁面。我們編寫JSP頁面,由Servlet容器轉換成Servlet并編譯成Java位元組碼檔案,當第一個該JSP頁面的請求到來時Servlet容器就會加載對應的Servlet并生成Servlet對象,後面的處理就跟前面所介紹的Servlet技術相同了。

是以,第一次請求JSP頁面的時候,總會比較慢,因為需要轉換成Servlet并編譯,再加載Servlet類檔案并生成Servlet執行個體。

當然,我們(就是Servlet容器的開發者)就必須改造Servlet容器,讓它能夠識别、轉換JSP頁面,然後能夠自動的編譯轉換成的Servlet代碼。這樣的Servlet容器就叫做JSP容器,是以合起來叫做Servlet/JSP容器。

Servlet/JSP容器甚至能夠自動檢測到JSP頁面的修改并重新編譯和加載,是以,我們修改JSP頁面後并不需要重新啟動Servlet/JSP容器。

可以說,JSP的核心原理/本質就是Servlet。

JSP基本文法

既然是HTML代碼中嵌入Java代碼,那麼JSP頁面的主體當然就是HTML,這部分就使用HTML的文法編寫。

那麼Servlet/JSP容器是如何識别嵌入的Java代碼呢?

JSP使用符号“”和“%>”來将Java代碼或與Java代碼相關的東西包圍住,比如:

  • “”和“--%>”及其中間的内容是JSP的注釋,它不會發送到浏覽器端,差別于HTML的注釋“”。
  • “”和“%>”及其中間的的内容是JSP的指令,用來設定頁面的一些參數,import依賴的Java包,包含其他JSP頁面等等。
  • “”和“%>”中間可以直接寫Java代碼,這叫JSP的腳本。
  • “”和“%>”及其中間的的内容是JSP的表達式,用來直接輸出表達式的計算結果。
  • “”和“%>”及其中間的的内容是JSP的聲明,用來聲明該頁面使用的變量和方法。

是以,Servlet/JSP容器一旦遇到上述的符号,它就知道該如何轉換成Java代碼了。

JSP其他技術

事實上,JSP技術在不斷的演化(任何技術都是這樣,演化就是為了進步,發現不足,解決不足)。

JSP其他的相關技術有:

  • JSP的動作,它很像HTML或XML的标簽,我猜測它就是使用下面的JSP的标簽技術實作的,比如:
  • JSP的标簽,這包括JSP自帶的标準标簽JSTL(JSP Standard Tag Library,即JSP标準标簽庫)、可以擴充自己所需要标簽的自定義标簽技術和标簽檔案技術。它的使用很像XML标簽,當然,擴充自己的标簽就比較複雜了。
  • 表達式語言(Expression Language,簡稱EL),似乎此技術與JSP技術是互相獨立的,但JSP裡面用它還是相當頻繁的,不知道當時開發EL是否主要就是為了在JSP中使用,我沒有去深究了。
  • JSP頁面片段,主要是為了消除重複,提高複用。

可以明确的是,目前JSP的主要用途就是起到一個模闆的作用,并盡量采用EL來通路應用資料,而不再使用JSP聲明、JSP表達式和JSP腳本來實作業務邏輯,業務邏輯交給獨立的Servlet來實作(當然,後來出現的MVC模式中Servlet僅用來充當控制器)。

這樣更好了解

我們把JSP頁面的内容分成兩大類:

  • 一類就是HTML代碼,這個就像編寫普通的HTML頁面那樣編寫就行,我們把這類代碼叫做模闆元素。
  • 另一類就是JSP相關的部分,這是通過規定的某種符号來識别的,這類代碼就叫做JSP文法元素。

無論如何,一個JSP頁面都會轉換成一個Servlet,即不管是模闆元素還是JSP文法元素,它最終都會轉換成Java代碼。

是以,轉換成的這些Java代碼必然在一個Servlet類的源代碼中,而Servlet接口中最重要的方法就是那個service()方法。

這樣看來,轉換成的這些Java代碼可以看作是service()方法中的内容,比如:

  • 模闆元素其實轉換成Java代碼就是:writer.println("")等類似這樣的。
  • JSP腳本則直接拷貝即可。
  • JSP隐式對象實際上是Servlet/JSP容器生成并傳進來的參數,比如request就是HttpServletRequest執行個體、application就是ServletContext執行個體、config就是ServletConfig執行個體、pageContext就是javax.servlet.jsp.PageContext執行個體、out是javax.servlet.jsp.JspWriter執行個體(類似從ServletResponse.getWriter()獲得的Writer)等等。
  • JSP表達式就轉換成:writer.print("表達式的計算結果")。
  • JSP動作和标簽肯定就轉換成對應的處理類的調用代碼。
  • EL則轉成通路附加到某個隐式對象的屬性中的資料,即getAttribute("xxx")名為xxx的屬性對象(它其實是你的業務實體類對象),然後就可以通路xxx中的資料。

還有一些則轉換成Servlet類檔案的其他内容,比如:

  • JSP的page指令導入Java包的部分。
  • JSP聲明可以聲明該頁面使用的變量和方法,即該頁面轉換成的Servlet類的成員變量和成員方法。

總結

現在,我們就可以使用JSP技術來改造前面的租房網應用了。

  • 我們要善于使用逆向思維;
  • 一旦你覺得寫代碼很繁瑣,很多重複的地方,那麼就表示哪裡有問題,或者應該改進,甚至有可能抽象出來一種新技術;
  • JSP的本質就是Servlet,因為它需要被轉換成Servlet;
  • JSP目前一般用來當HTML模闆,僅使用EL來通路資料,而不在其中編寫Java腳本了。

繼續閱讀