JSP(全稱JavaServerPages)是由Sun Microsystems公司倡導和許多公司參與共同創建的一種使軟件開發者可以響應客戶端請求,而動態生成HTML、xml或其他格式文檔的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高級提煉而作為JAVA Servlet2.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 EE5的一部分,在JSR-245中發布。
靜態數據在輸入文件中的內容和輸出給HTTP響應的內容完全一致。此時,該JSP輸入文件會是一個沒有內嵌JAVA或動作的HTML頁面。而且,客戶端每次請求都會得到相同的響應內容。
JSP指令JSP指令控制JSP編譯器如何去生成servlet,以下是可用的指令:
<%@ include file="somefile.jsp" %>
import | 使一個JAVA導入聲明被插入到最終頁面文件。 |
contentType | 規定了生成內容的類型。當生成非HTML內容或者當前字符集character set并非默認字符集時使用。 |
errorPage | 處理HTTP請求時,如果出現異常則顯示該錯誤提示信息頁面。 |
isErrorPage | 如果設置為TRUE,則表示當前文件是一個錯誤提示頁面。 |
isThreadSafe | 表示最終生成的servlet是否線程安全(threadsafe)。 |
<%@ 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 prefix="myprefix" uri="taglib/mytag.tld" %>JSP腳本元素和變量標準腳本變量
以下是永遠可用的腳本變量:
有三個基本的腳本元素,作用是使JAVA代碼可以直接插入servlet.
<%! int serverInstanceVariable = 1; %>
<% int localStackBasedVariable = 1; out.println(localStackBasedVariable); %>
<%= "expanded inline data " + 1 %>
JSP動作是一系列可以調用內建于網絡服務器中的功能的XML標簽。JSP提供了以下動作:
jsp:include | 和子過程類似,JAVA SERVLET暫時接管對其它指定的JSP頁的請求和響應。當處理完該JSP頁后就馬上把控制權交還當前JSP頁。這樣JSP代碼就可以在多個JSP頁中共享而不用復制。 |
jsp:param | 可以在jsp:include, jsp:forward或jsp:params塊之間使用。指定一個將加入請求的當前參數組中的參數。 |
jsp:forward | 用于處理對另一個JSP或SERVLET的請求和響應??刂茩嘤肋h不會交還給當前JSP頁。 |
jsp:plugin | Netscape Navigator的老版本和Internet Explorer使用不同的標簽以嵌入一個applet。這個動作產生為嵌入一個APPLET所需要的指定瀏覽器標簽。 |
jsp:fallback | 如果瀏覽器不支持APPLETS則會顯示的內容。 |
jsp:getProperty | 從指定的JavaBean中獲取一個屬性值。 |
jsp:setProperty | 在指定的JavaBean中設置一個屬性值。 |
jsp:useBean | 創建或者復用一個JavaBean變量到JSP頁。 |
1 <html>2 <head></head>3 <body>4 <jsp:include page="mycommon.jsp" >5 <jsp:param name="extraparam" value="myvalue" />6 </jsp:include>7 name:<%=request.getParameter("extraparam")%>8 </body>9 </html>jsp:forward
1 <jsp:forward page="subpage.jsp" >2 <jsp:param name="forwardedFrom" value="this.jsp" />3 </jsp:forward>
在本例中,請求被傳遞到"subpage.jsp",而且請求的處理權不會再返回前者。
jsp:plugin1 <jsp:plugin type=applet height="100%" width="100%" 2 archive="myjarfile.jar,myotherjar.jar" 3 codebase="/applets" 4 code="com.foo.MyApplet" > 5 <jsp:params> 6 <jsp:param name="enableDebug" value="true" /> 7 </jsp:params> 8 <jsp:fallback> 9 Your browser does not support applets.10 </jsp:fallback>11 </jsp:plugin>View Code
上述plugin例子說明了一種在網頁中嵌入applet的統一方法。在<OBJECT>標簽出現之前,并沒有一種嵌入applets的通用方法。這個標簽設計得并不好,但有希望在以后加入動態屬性(height="${param.height}", code="${chart}"等)和動態參數的新功能。目前jsp:plugin標簽不允許動態調用applets。例如,你如果有一個圖表applet需要數據點以參數形式被傳入,除非數據點的數量是一個常量,否則你就不能使用ResultSet循環來創建jsp:param標簽,你不得不手寫每個jsp:param標簽的代碼。而每個上述jsp:param標簽可以有一個動態命名和動態值。
jsp:useBean1 <jsp:useBean id="myBean" class="com.foo.MyBean" scope="request" />2 <jsp:getProperty name="myBean" property="lastChanged" />3 <jsp:setProperty name="myBean" property="lastChanged" value="<%= new Date()%>" />View Code
scope屬性可以是request, page, session or application,它有以下用意:
上述例子將會用一個創建一個類的實例,并且把該實例存儲在屬性中,該屬性將在該請求的生命周期內有效。它可以在所有被包含或者從主頁面(最先接收請求的頁面)轉向到的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()方法將會返回如下之一:
當結束標簽出現時,它會調用doEndTag()方法,該方法會返回如下兩做之一:
上述myaction標簽tag會有一個類似下面例子的用于實現的類:
1 public class MyActionTag extends TagSupport { 2 //Releases all instance variables. 3 public void release() {...} 4 5 public MyActionTag() { ... } 6 7 //called for the start tag 8 public int doStartTag() { ... } 9 10 //called at the end tag11 }View Code本地化
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頁。有幾種平臺都基于服務于網絡層的模-視圖-控件 模式(比如Struts和Spring framework)。
樣例不管JSP編譯器是生成SERVLET的JAVA源碼,或者是直接發布二進制碼,了解一下JSP編譯器是如何把文件轉換成一個JAVA SERVLET,都是很有幫助的。例如,看一下如下輸入JSP和它最后生成的JAVA SERVLET:
Input JSP
1 <%@ page errorPage="myerror.jsp" %> 2 <%@ page import="com.foo.bar" %> 3 4 <html> 5 <head> 6 <%! int serverInstanceVariable = 1;%> 7 ... 8 <% int localStackBasedVariable = 1; %> 9 <table>10 <tr><td><%= "expanded inline data " + 1 %></td></tr>11 ...View Code
Resulting servlet
1 package jsp_servlet; 2 import java.util.*; 3 import java.io.*; 4 import javax.servlet.*; 5 import javax.servlet.http.*; 6 import javax.servlet.jsp.*; 7 import javax.servlet.jsp.tagext.*; 8 9 import com.foo.bar; //imported as a result of <%@ page import="com.foo.bar" %>10 import ...11 12 class _myserlvet implements javax.servlet.Servlet, javax.servlet.jsp.HttpJspPage {13 //inserted as a14 //result of <%! int serverInstanceVariable = 1;%>15 int serverInstanceVariable = 1;16 ...17 18 public void _jspService( javax.servlet.http.HttpServletRequest request,19 javax.servlet.http.HttpServletResponse response )20 throws javax.servlet.ServletException,21 java.io.IOException22 {23 javax.servlet.ServletConfig config = ...;//get the servlet config24 Object page = this;25 PageContext pageContext = ...;//get the page context for this request26 javax.servlet.jsp.JspWriter out = pageContext.getOut();27 HttpSession session = request.getSession( true );28 try {29 out.print( "<html>/r/n" );30 out.print( "<head>/r/n" );31 ...32 //from <% int localStackBasedVariable = 1; %>33 int localStackBasedVariable = 1;34 ...35 out.print( "<table>/r/n" );36 out.print( " <tr><td>" );37 //note, toStringOrBlank() converts the expression into a string or if38 // the expression is null, it uses the empty string.39 //from <%= "expanded inline data " + 1 %>40 out.print( toStringOrBlank( "expanded inline data " + 1 ) );41 out.print( " </td></tr>/r/n" );42 ...43 } catch ( Exception _exception ) {44 //clean up and redirect to error page in <%@ page errorPage="myerror.jsp" %>45 }46 }47 }View Code出版物
JavaServer Pages, Third Edition,Hans Bergsten,O'Reilly & Associates, Inc.,Sebastopol, California, 2003.ISBN 0-596-00563-6
關注交流
個人公眾微信公眾號:華少
新聞熱點
疑難解答