JSP

JSP（全稱Jakarta Server Pages，曾稱為JavaServer Pages）是由昇陽電腦公司主導建立的一種動態網頁技術標準。JSP部署於網絡服務器上，可以響應客戶端發送的請求，並根據請求內容動態地生成HTML、XML或其他格式文檔的Web網頁，然後返回給請求者。JSP技術以Java語言作為腳本語言，為用戶的HTTP請求提供服務，並能與服務器上的其它Java程序共同處理複雜的業務需求。
JSP將Java程序碼和特定變動內容嵌入到靜態的頁面中，實現以靜態頁面為模板，動態生成其中的部分內容。JSP引入了被稱為“JSP動作”的XML標籤，用來調用內建功能。另外，可以創建JSP標籤庫，然後像使用標準HTML或XML標籤一樣使用它們。標籤庫能增強功能和服務器性能，而且不受跨平臺問題的限制。JSP文件在運行時會被其編譯器轉換成更原始的Servlet程序碼。JSP編譯器可以把JSP文件編譯成用Java程序碼寫的Servlet，然後再由Java編譯器來編譯成能快速執行的二進制機器碼，也可以直接編譯成二進制碼。

**綜述**
JSP從2.0版本開始，增加了表達式語言（EL），以提供更快更簡單的創建新標籤的方法，並允許開發者創建Velocity式模板。如舊版本代碼“Hello, ”可簡化為“Hello, ${param.visitor}”。

**特點**
 能以模板化的方式簡單、高效地添加動態網頁內容。- 可利用JavaBean和標籤庫技術複用常用的功能代碼（設計好的組件容易實現重複利用，減少重複勞動）。標籤庫不僅帶有通用的內置標籤（JSTL)，而且支持可擴展功能的自定義標籤。- 有良好的工具支持。- 繼承了Java語言的相對易用性。- 繼承了Java的跨平臺優勢，實現“一次編寫，處處運行”。因為支持Java及其相關技術的開發平臺多，網站開發人員可以選擇在最適合自己的系統平臺上進行JSP開發；不同環境下開發的JSP項目，在所有客戶端上都能順利訪問。- 頁面中的動（控制變動內容的部分）／靜（內容不需變動的部分）區域以分散但又有序的形式組合在一起，能使人更直觀地看出頁面代碼的整體結構，也使得設計頁面效果和程序邏輯這2部分工作容易分離（外觀視圖與邏輯分離）。從而方便分配人員併發揮各自長處，實現高效地分工合作。- 可與其它企業級Java技術相互配合。JSP可以只專門負責頁面中的數據呈現，實現分層開發。

**包含內容**

**JSP指令**
JSP指令控制JSP編譯器如何去生成servlet，以下是可用的指令：- 包含指令include –包含指令通知JSP編譯器把另外一個文件完全包含入當前文件中。效果就好像被包含文件的內容直接被粘貼到當前文件中一樣。這個功能和C預處理器所提供的很類似。被包含文件的擴展名一般都是"jspf"（即JSP Fragment，JSP片段）:- 頁面指令page –頁面指令有以下幾個選項：
//example import導入樣例
//example contentType頁面類型樣例
//example for non error page無錯誤頁面樣例
//example for a thread safe JSP執行序安全JSP樣例
注意：在同一個JSP文件中只有“import”導入頁面指令可以被多次使用。- 標籤庫指令taglib –標籤庫指令描述了要使用的JSP標籤庫。該指令需要指定一個前綴prefix（和C++的命名空間很類似）和標籤庫的描述URI:

**JSP腳本元素和變量**

**標準腳本變量**
以下是永遠可用的腳本變量：- out：JSPWriter，用來寫入響應流的數據- page：servlet自身- pageContext：一個PageContext實例包括和整個頁面相聯繫的數據，一個給定的HTML頁面可以在多個JSP之間傳遞。- request：HTTP request（請求）對象- response：HTTP response（響應）對象- session：HTTP session（服務端會話）對象

**腳本元素**
有三個基本的腳本元素，作用是使JAVA代碼可以直接插入servlet.- 一種是聲明標籤，在JAVA SERVLET的類體中放入一個變量或方法的定義。靜態的數據成員也可以如此定義。
*: - 一種是腳本標籤，在JAVA SERVLET的類的_jspService()方法中放入所包含的語句。
*: - 一種是表達式標籤，在JAVA SERVLET的類中放入待賦值的表達式，表達式注意不能以分號結尾。
*: 

**JSP動作**
JSP動作是一系列可以調用內建於網絡服務器中的功能的XML標籤。JSP提供了以下動作：

**標籤樣例**

**= jsp:include =**

name:

**= jsp:forward =**

在本例中，請求被傳遞到"subpage.jsp"，而且請求的處理權不會再返回前者。

**= jsp:useBean =**
" />
scope屬性可以是request, page, session or application，它有以下用意：- request— 該屬性在請求的生命週期內有效，一旦請求被所有的JSP頁處理完後，那麼該屬性就不可引用。- page— 該屬性只是當前頁中有效。- session— 該屬性在用戶會話的生命週期內有效。- application— 該屬性在各種情況下都有效，並且永遠不會被變為不可引用，和全局變量global variable相同。
上述例子將會用一個創建一個類的實例，並且把該實例存儲在屬性中，該屬性將在該請求的生命週期內有效。它可以在所有被包含或者從主頁面（最先接收請求的頁面）轉向到的JSP頁之間共享。

**JSP標籤庫**
除了JSP預定義動作之外，開發者還可以使用JSP標籤擴展API添加他們自定義的動作。開發者寫一種實現一個標籤的界面和一個標籤庫的XML描述文件的JAVA類，這就能指定標籤和實現標籤的JAVA類
請看如下JSP：
...

...

...
JSP編譯器將會載入mytaglib.tld這個XML文件，然後可以看到標籤myaction由JAVA類MyActionTag實現。當該標籤首次在文件中使用時，將會創建一個MyActionTag的實例。然後（而且當每次該標籤被使用時），當出現開始標籤時，將會調用doStartTag()方法，根據開始標籤的結果，來決定如何處理標籤的主體。主體是指開始標籤和結束標籤之間的文本。這個doStartTag()方法將會返回如下之一：- SKIP_BODY - 標籤之間不做處理。- EVAL_BODY_INCLUDE - 對標籤之內主體進行賦值。- EVAL_BODY_TAG - 對標籤之內主體進行賦值並把結果輸出到流（保存在標籤的主體內容屬性中）。
注意：如果標籤擴展了BodyTagSupport類，當主體被執行時會在調用doEndTag()之前調用doAfterBody()方法。該方法用於實現循環結構。
當結束標籤出現時，它會調用doEndTag()方法，該方法會返回如下兩做之一：- EVAL_PAGE - 表示JSP文件的剩餘部份將會被執行。this indicates that the rest of the JSP file should be processed.- SKIP_PAGE - 表示將不會再有更多執行操作。當前JSP頁交出控制權。就象在轉發動作中的作用一樣。
上述myaction標籤tag會有一個類似下面例子的用於實現的類：
public class MyActionTag extends  TagSupport {
//Releases all instance variables.
public void release() {...}
public MyActionTag() { ... }
//called for the start tag
public int doStartTag() { ... }
//called at the end tag
}

**本地化**
JSP的本地化是通過和JAVA應用程序相同的方式完成的，即使用資源包。

**模型-視圖-控制器 模式**
為了把表現層（presentation）從請求處理（request processing）和數據存儲（data storage）中分離開來（這樣更利於開發、查錯和功能擴展），昇陽公司推薦在JSP文件中使用一種稱作模型-視圖-控制器（MVC）的架構模式。按照此設計，當用戶訪問網站上的特定網址時，用戶的處理請求會先由網站服務器獲取到，然後先交由網站的控制器程序作初步處理。用戶的訪問請求可能多種多樣，比如查詢信息或進行數據計算都是常見的網站業務。控制器程序會初步判斷用戶請求的種類，然後把用戶請求轉發給與特定業務對應的Servlet程序或者另一個獨立的JSP文件進行業務處理。當請求處理完後，再通過一個專門負責輸出信息的JSP頁以清晰、美觀的方式向用戶的瀏覽器輸出結果。簡而言之，先由控制器攔截用戶請求並做初步判斷，再由業務處理程序訪問數據（從數據庫中訪問）和處理業務，最後由視圖組件生成結果頁面併發送結果給用戶。其中JSP一般用作展示輸出結果，可以用於展示經Servlet查詢或處理後的結果；也可以用一個JSP文件處理業務邏輯，再用另一個JSP文件展示結果。按功能做這樣的文件拆分（而非由一個臃腫的JSP頁面包攬所有功能）是為了便於團隊分工。MVC本身是一種由來已久的設計思想，基於JSP的技術只是實現MVC架構的流行方案之一。Struts和Spring框架等好幾種流行的網站建設框架都是基於MVC模式設計的。

**JSP和Servlets**
一個JSP頁面的生命週期
從架構上說，JSP可以被看作是從Servlets高級提煉而作為Java Servlet 2.1 API的擴展而應用。Servlets和JSP最早都是由昇陽電腦開發的。從JSP1.2版本以來，JSP處於JCP開發模式下。JSR-53規定了JSP 1.2和Servlet 2.4的規範，JSR-152規定了JSP 2.0的規範。2006年5月，JSP 2.1的規範作為Java EE 5的一部份，在JSR-245中發佈。
靜態數據在輸入文件中的內容和輸出給HTTP響應的內容完全一致。此時，該JSP輸入文件會是一個沒有內嵌JAVA或動作的HTML頁面。而且，客戶端每次請求都會得到相同的響應內容。

**樣例**
不管JSP編譯器是生成SERVLET的JAVA源碼，或者是直接發佈二進制碼，瞭解一下JSP編譯器是如何把文件轉換成一個JAVA SERVLET，都是很有幫助的。例如，看一下如下輸入JSP和它最後生成的JAVA SERVLET：
輸入JSP
...

...
最後生成的JAVA SERVLET
package jsp_servlet;
import java.util.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import com.foo.bar; //imported as a result of 
import ...
class _myserlvet implements javax.servlet.Servlet, javax.servlet.jsp.HttpJspPage {
//inserted as a
//result of 
int serverInstanceVariable = 1;
...
public void _jspService( javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response )
throws javax.servlet.ServletException,
java.io.IOException
{
javax.servlet.ServletConfig config = ...;//get the servlet config
Object page = this;
PageContext pageContext = ...;//get the page context for this request
javax.servlet.jsp.JspWriter out = pageContext.getOut();
HttpSession session = request.getSession( true );
try {
out.print( "\r\n" );
out.print( "\r\n" );
...
//from 
int localStackBasedVariable = 1;
...
out.print( "\r\n" );
out.print( "   " );
//note, toStringOrBlank() converts the expression into a string or if
// the expression is null, it uses the empty string.
//from 
out.print( toStringOrBlank( "expanded inline data " + 1 ) );
out.print( "   \r\n" );
...
} catch ( Exception _exception ) {
//clean up and redirect to error page in 
}
}
}

**參見**
 JSTL- Java企業版- JavaServer Faces- Java Servlet- SSJS- WAR (file format)- EAR (file format)- JAR (file format)- Tomcat服務器

**參考資料**

**文內引用**

**書目**
 cite book |title=JavaServer Pages |author=Hans Bergsten |url=http://www.amazon.com/gp/product/0596005636 |publisher=O'Reilly |location=Sebastopol, California |edition=3 |ISBN=0-596-00563-6 |year=2003 |access-date=2006-07-20 |archive-date=2019-10-17 |archive-url=https://web.archive.org/web/20191017183656/https://www.amazon.com/gp/product/0596005636 |dead-url=no 

**外部鏈接**
  Sun's JSP product descriptiondate=20100105041505 -  JSR 245date=20100617225735  (JSP 2.1)-  JSR 152date=20091023192028  (JSP 2.0)-  JSR 53date=20100612204354  (JSP 1.2)