本頁使用了標題或全文手工轉換

JSP

維基百科,自由的百科全書
前往: 導覽搜尋
JSP
副檔名 .jsp
網路媒體型式 application/jsp
穩定版本 2.2
標準 JSR 245
網站 JavaServer Pages Technology

JSP(全稱JavaServer Pages)是由Sun Microsystems公司倡導和許多公司參與共同建立的一種使軟體開發者可以響應客戶端請求,而動態生成HTMLXML或其他格式文件的Web網頁的技術標準。JSP技術是以Java語言作為手稿語言的,JSP網頁為整個伺服器端的Java庫單元提供了一個介面來服務於HTTP的應用程式。

JSP使Java代碼和特定的預定義動作可以嵌入到靜態頁面中。JSP句法增加了被稱為JSP動作的XML標籤,它們用來呼叫內建功能。另外,可以建立JSP標籤庫,然後像使用標準HTML或XML標籤一樣使用它們。標籤庫提供了一種和平台無關的擴充功能伺服器效能的方法。

JSP被JSP編譯器編譯成Java Servlets。一個JSP編譯器可以把JSP編譯成JAVA代碼寫的servlet然後再由JAVA編譯器來編譯成機器碼,也可以直接編譯成二進制碼。

JSP和Servlets[編輯]

從架構上說,JSP可以被看作是從Servlets高階提煉而作為JAVA Servlet 2.1 API的擴充功能而應用。Servlets和JSP最早都是由Sun Microsystems(太陽公司)開發的。從JSP1.2版本以來,JSP處於Java Community Process(有人譯為:JAVA社群組織)開發模式下。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指令[編輯]

JSP指令控制JSP編譯器如何去生成servlet,以下是可用的指令:

  • 包含指令include –包含指令通知JSP編譯器把另外一個檔案完全包含入當前檔案中。效果就好像被包含檔案的內容直接被貼上到當前檔案中一樣。這個功能和C預處理器所提供的很類似。被包含檔案的副檔名一般都是"jspf"(即JSP Fragment,JSP碎片):
<%@ include file="somefile.jsp" %>
  • 頁面指令page –頁面指令有以下幾個選項:
import 使一個JAVA匯入宣告被插入到最終頁面檔案。
contentType 規定了生成內容的類型。當生成非HTML內容或者當前字符集character set並非預設字符集時使用。
errorPage 處理HTTP請求時,如果出現異常則顯示該錯誤提示資訊頁面。
isErrorPage 如果設定為TRUE,則表示當前檔案是一個錯誤提示頁面。
isThreadSafe 表示最終生成的servlet是否執行緒安全(thread safe)。
<%@ page import="java.util.*" %> //example import导入样例
<%@ page contentType="text/html" %> //example contentType页面类型样例
<%@ page isErrorPage=false %> //example for non error page无错页面样例
<%@ page isThreadSafe=true %> //example for a thread safe JSP线程安全JSP样例

注意:在同一個JSP檔案中只有"import"匯入頁面指令可以被多次使用。

  • 標籤庫指令taglib –標籤庫指令描述了要使用的JSP標籤庫。該指令需要指定一個字首prefix(和C++的命名空間很類似)和標籤庫的描述URI:
<%@ taglib prefix="myprefix" uri="taglib/mytag.tld" %>

JSP指令碼元素和變數[編輯]

標準指令碼變數[編輯]

以下是永遠可用的指令碼變數:

  • out:JSPWriter,用來寫入響應流的資料
  • page:servlet自身
  • pageContext:一個PageContext例項包括和整個頁面相聯繫的資料,一個給定的HTML頁面可以在多個JSP之間傳遞。
  • request:HTTP request(請求)物件
  • response:HTTP response(響應)物件
  • session:HTTP session(伺服端會話)物件

指令碼元素[編輯]

有三個基本的指令碼元素,作用是使JAVA代碼可以直接插入servlet.

  • 一種是宣告標籤,在JAVA SERVLET的類體中放入一個變數的定義。靜態的成員變數也可以如此定義。
    <%! int serverInstanceVariable = 1; %>
    
  • 一種是指令碼標籤,在JAVA SERVLET的類的_jspService()方法中放入所包含的語句。
    <% int localStackBasedVariable = 1;  out.println(localStackBasedVariable); %>
    
  • 一種是運算式標籤,在JAVA SERVLET的類中放入待賦值的運算式,運算式注意不能以分號結尾。
    <%= "expanded inline data " + 1 %>
    

JSP動作[編輯]

JSP動作是一系列可以呼叫內建於網路伺服器中的功能的XML標籤。JSP提供了以下動作:

jsp:include 和子過程類似,JAVA SERVLET暫時接管對其它指定的JSP頁的請求和響應。當處理完該JSP頁後就馬上把控制權交還當前JSP頁。這樣JSP代碼就可以在多個JSP頁中共享而不用複製。
jsp:param 可以在jsp:include, jsp:forward或jsp:params塊之間使用。指定一個將加入請求的當前參陣列中的參數。
jsp:forward 用於處理對另一個JSP或SERVLET的請求和響應。控制權永遠不會交還給當前JSP頁。
jsp:plugin Netscape Navigator的老版本和Internet Explorer使用不同的標籤以嵌入一個applet。這個動作產生為嵌入一個APPLET所需要的指定瀏覽器標籤。
jsp:fallback 如果瀏覽器不支援APPLETS則會顯示的內容。
jsp:getProperty 從指定的JavaBean中取得一個屬性值。
jsp:setProperty 在指定的JavaBean中設定一個屬性值。
jsp:useBean 建立或者復用一個JavaBean變數到JSP頁。

標籤樣例[編輯]

jsp:include[編輯]
<html>
<head></head>
<body>
<jsp:include page="mycommon.jsp" >
    <jsp:param name="extraparam" value="myvalue" />
</jsp:include>
name:<%=request.getParameter("extraparam")%>
</body>
</html>
jsp:forward[編輯]
<jsp:forward page="subpage.jsp" >
     <jsp:param name="forwardedFrom" value="this.jsp" />
</jsp:forward>

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

jsp:plugin[編輯]
<jsp:plugin type=applet height="100%" width="100%"
            archive="myjarfile.jar,myotherjar.jar"
            codebase="/applets"
            code="com.foo.MyApplet" >
    <jsp:params>
        <jsp:param name="enableDebug" value="true" />
    </jsp:params>
    <jsp:fallback>
        Your browser does not support applets.
    </jsp:fallback>
</jsp:plugin>

上述plugin例子說明了一種在網頁中嵌入applet的統一方法。在<OBJECT>標籤出現之前,並沒有一種嵌入applets的通用方法。這個標籤設計得並不好,但有希望在以後加入動態屬性(height="${param.height}", code="${chart}"等)和動態參數的新功能。目前jsp:plugin標籤不允許動態呼叫applets。例如,你如果有一個圖表applet需要資料點以參數形式被傳入,除非資料點的數量是一個常量,否則你就不能使用ResultSet迴圈來建立jsp:param標籤,你不得不手寫每個jsp:param標籤的代碼。而每個上述jsp:param標籤可以有一個動態命名和動態值。

jsp:useBean[編輯]
<jsp:useBean id="myBean" class="com.foo.MyBean" scope="request" />
<jsp:getProperty name="myBean" property="lastChanged" />
<jsp:setProperty name="myBean" property="lastChanged" value="<%= new Date()%>" />

scope屬性可以是request, page, session or application,它有以下用意:

  • request— 該屬性在請求的生命周期內有效,一旦請求被所有的JSP頁處理完後,那麼該屬性就不可參照。
  • page— 該屬性只是當前頁中有效。
  • session— 該屬性在用戶會話的生命周期內有效。
  • application— 該屬性在各種情況下都有效,並且永遠不會被變為不可參照,和全局變數global variable相同。

上述例子將會用一個建立一個類的例項,並且把該例項儲存在屬性中,該屬性將在該請求的生命周期內有效。它可以在所有被包含或者從首頁面(最先接收請求的頁面)轉向到的JSP頁之間共享。

JSP標籤庫[編輯]

除了JSP預定義動作之外,開發者還可以使用JSP標籤擴充功能API添加他們自訂的動作。開發者寫一種實作一個標籤的介面和一個標籤庫的XML描述檔案的JAVA類,這就能指定標籤和實作標籤的JAVA類 請看如下JSP:

<%@ taglib uri="mytaglib.tld" prefix="myprefix" %>
...
<myprefix:myaction> <%-- the start tag %>
...
</myprefix:myaction> <%-- the end tag %>
...

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應用程式相同的方式完成的,即使用資源包

JSP 2.0[編輯]

新的JSP規範版本包括新的用於提升程式設計師工作效率功能,主要有:

Hello, ${param.visitor}  <%-- same as: Hello, <%=request.getParameter("visitor")%> --%>

模型-檢視-控制器 模式[編輯]

為了把表現層presentation從請求處理request processing和資料儲存data storage中分離開來,太陽公司推薦在JSP檔案中使用一種模型-檢視-控制器Model-view-controller模式。規範的SERVLET或者分離的JSP檔案用於處理請求。當請求處理完後,控制權交給一個只作為建立輸出作用的JSP頁。有幾種平台都基於服務於網路層的模-檢視-控制項 模式(比如StrutsSpring framework)。

樣例[編輯]

不管JSP編譯器是生成SERVLET的JAVA源碼,或者是直接發行二進制碼,了解一下JSP編譯器是如何把檔案轉換成一個JAVA SERVLET,都是很有幫助的。例如,看一下如下輸入JSP和它最後生成的JAVA SERVLET:

Input JSP

<%@ page errorPage="myerror.jsp" %>
<%@ page import="com.foo.bar" %>
 
<html>
<head>
<%! int serverInstanceVariable = 1;%>
...
<% int localStackBasedVariable = 1; %>
<table>
    <tr><td><%= "expanded inline data " + 1 %></td></tr>
    ...

Resulting 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 <%@ page import="com.foo.bar" %>
import ...
 
class _myserlvet implements javax.servlet.Servlet, javax.servlet.jsp.HttpJspPage {
    //inserted as a
    //result of <%! int serverInstanceVariable = 1;%>
    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( "<html>\r\n" );
             out.print( "<head>\r\n" );
             ...
             //from <% int localStackBasedVariable = 1; %>
             int localStackBasedVariable = 1;
             ...
             out.print( "<table>\r\n" );
             out.print( "   <tr><td>" );
             //note, toStringOrBlank() converts the expression into a string or if
             // the expression is null, it uses the empty string.
             //from <%= "expanded inline data " + 1 %>
             out.print( toStringOrBlank( "expanded inline data " + 1 ) );
             out.print( "   </td></tr>\r\n" );
             ...
        } catch ( Exception _exception ) {
           //clean up and redirect to error page in <%@ page errorPage="myerror.jsp" %>
        }
    }
}

出版物[編輯]

參見[編輯]

外部連結[編輯]