天天看點

第三章_JSP

jsp頁面實在jsp容器中運作的。servlet容器一般也是jsp容器。例如,tomcat就是一個servlet/jsp容器。

第一次請求一個jsp頁面時,servlet/jsp容器要做兩件事情:

2、如果轉換成功,servlet/jsp容器将會編譯servlet類。

jsp頁面可以使用兩種備注:

1、jsp備注。說明該頁面的作用

2、html/xhtml備注。這些将被發送到浏覽器。

jsp備注以<%--開頭,以--%>結束。例如,下面就是一個jsp備注:

<%-- retrieve products to display --%>

jsp備注不會被發送到浏覽器,也不能進行嵌套。

html/xhtml備注不是由容器進行處理,而是被發送到浏覽器。html/xhtml備注的用途之一是辨別jsp頁面:

<!-- this is /jsp/store/displayproducts.jspf -->

在處理帶有許多jsp片段的應用程式時,這個特别有用。開發者通過檢視浏覽器的html源代碼,可以輕松查出某個html代碼部分生成了哪個jsp頁面或者哪個片段。

jsp中存在9個隐式對象:request、response、out、session、application、config、pagecontext、page、exception。

指令是第一種jsp句法元素,其訓示jsp轉換器應該如何将某個jsp頁面轉換成servlet的指令。最重要的是這兩個:page和include。

page指令的文法如下:

<%@ page attrubute1=”value1” attribute=”value2” ...%>

@和page之間的空格是可選的,attribute1、attribute2等都是page指令的屬性。下面是page指令的屬性清單:

import。指定要導入的一種或多種java類型,供本頁的java代碼所用。例如:import=”java.util.list”。

session。值為true時,表示這個頁面參與session管理;值為false時,表示不參與session管理。預設值為true,意味着如果之前還沒有javax.servlet.http.httpsession執行個體,那麼調用jsp頁面将始終會建立一個。

buffer。指定隐式對象out的緩沖區大小,以千位元組為機關。

autoflush。預設值為true,表示當緩沖區滿時,杯緩存的輸出應該自動重新整理。值為false時,表示隻有在調用隐式對象response的flush方法時,才進行重新整理緩沖區。是以,當緩沖區溢出時會抛出一個異常。

isthreadsafe。表示頁面中實作的線程安全級别。建議jsp的作者不要使用這個屬性,因為它會産生一個包涵不建議使用的代碼的servlet。

info。指定所生成servlet的getservletinfo方法傳回值。

errorpage、表示負責處理該頁面可能出現的錯誤的頁面。

iserrorpage。表明這個頁面是否負責處理錯誤。

contenttype。指定該頁面隐式對象response的内容類型,其預設值為text/html。

pageencoding。指定該頁面的字元編碼,其預設值為iso-8859-1.

iselignored。表名是否忽略el表達式。el是expression language的縮寫。

language。指定該頁面使用的腳本語言,其預設值為java。

extends。指定這個jsp頁面的實作類必須擴充的超類。該屬性很少使用,使用時應該特别小心。

deferredsyntaxallowedasliteral。指明是否允許用字元序列#{做為該頁面和編譯單元的string字面值,其預設值為false。#{很重要,因為它在el表達式中是一個特殊的字元序列。

trimdirectivewhitespaces。表明是否從輸出内容中删除隻包含空格的模版文本,其預設值為false,也就是說,不删除空格。

page指令也可以多次出現。但是,在多個page指令中多次出現的同一個屬性,它的值必須一緻,隻有import屬性例外。放在多個page指令中的import屬性,其效果可以累積。例如,下面的page指令将會同時導入java.util.arraylist和java.io.file

<% @page import=”java.util.arraylist”%>

<% @page import=”java.io.file”%>

其結果與下面的這行代碼相同:

<% @page import=”java.util.arraylist, java.util.date”%>

下面再舉個例子。這個page指令将session屬性值設為false,并将頁面的緩沖區容量設為16kb

<% @page session=”false” buffer=”16kb”%>

include指令的文法如下:

<%@ include file=”url”%>

此處@和include之間的空格是可選的,并且url是表示一個include檔案的相對路徑,如果url以一個正斜線(/)開頭,那麼其在伺服器中就會杯解讀成是一條絕對路徑。如果不是以正斜線開頭,則被解讀為是相對于目前jsp頁面的路徑。

按照規範,include檔案的擴充名應為jspf,表示為jsp fragment。如今。jsp fragment也稱作jsp segmen,隻是為了保持一緻,仍然用jspf做為擴充名。

第二種jsp句法元素是腳本元素,它将java代碼合并成一個jsp頁面。腳本元素有3種類型:scriplet、聲明及表達式。

scriptlet是一個java代碼塊,它以<%開頭,以%>結束。

表達式的運算結果會杯填入隐式對象out的print方法中。表達式以<%開頭,并以%>結束。例如,下面就是一個表達式:

today is <%=java.util.calendar.getinstance().gettime()%>

注意:表達式後面不需要用分号。

這個表達式和下面的scriplet是一樣的

<%

out.print(java.util.calendar.getinstance().gettime()) ;

%>

聲明能夠在jsp頁面中使用變量和方法。聲明要用<%!和%>包起來。下面就聲明了一個方法。

<%!

public string gettodaysdate(){

return new java.util.date() ;

}

聲明可以放在jsp頁面中的任何位置,并且同一個頁面中可以有多個聲明。

我們可以利用聲明覆寫實作類中的init和destroy方法。覆寫init,要聲明一個jspinit方法;覆寫destroy,要聲明一個jspdestroy方法。例如:

public void jspinit(){

system.out.println(“jspinit...”) ;

public void jspdestroy(){

system.out.println(“jspdestroy...”) ;

随着jsp2.0中el的發展,建議做法是利用el來通路伺服器的對象,而不是在jsp頁面中編寫java代碼。為此,原本開啟的jsp2.0腳本元素,可以通過在部署描述符的<jsp-property-group>中定義一個scripting-invalid元素,将它關閉,如下所示:

<jsp-property-group>

<url-pattern>*.jsp</url-pattern>

<scripting-invalid>true</scripting-invalid>

</jsp-property-group>

這個動作将建立一個與某個java對象相關的腳本變量。它将是表現邏輯與業務邏輯分割開來最容易的方法之一。但是有了像定制标簽和el這類技術之後,現在已經很少使用usebean了。

<jsp:usebean id=”today” class=”java.util.date”/>

<jsp:usebean id=”employee” class=”app03a.employee”/>

<jsp:setproperty name=”employee” property=”fitstname” value=”abigail”>

first name:<jsp:getproperty name=”employee” property=”firstname”/>

include動作用于動态地包含另一個資源,它可以包含另一個jsp頁面、一個servlet或者一個靜态的html頁面。

<jsp:include page=”jspf/menu.jsp”>

</jsp:include>

了解include指令和include動作之間的差別是很重要的。使用include指令時,這種包含是發生在頁面轉換的時候,例如jsp容器将頁面轉換成一個生成的servlet的時候。使用include動作時,這種包含則是發生在請求的時候。是以,可以利用include動作傳遞參數,而不是利用include指令。

第二個差別在于,使用include指令時,杯包含資源的檔案擴充名并不重要。而使用include動作時,檔案擴充名則必須為jsp,以便它能夠做為一個jsp頁面進行處理。例如,在include動作中用jspf做為擴充名時,将會使得這個jsp segment被當作靜态檔案進行處理。

forward動作是将目前頁面跳轉到另一個不同的資源。例如,下面的forward動作就是将目前頁面跳轉到login.jsp頁面。

<jsp:forward page=”jspf/login.jsp”>

</jsp:forward>

在jsp中錯誤處理支援得很好。你可以利用try語句處理java代碼,也可以指定一個頁面,讓他在應用程式遇到未捕捉的異常時顯示出來,那麼,一旦發生異常,使用者将會看到一張經過精心設計的頁面,解釋目前發生了什麼狀況,而不是用一條錯誤消息打發使用者,讓他們皺眉不已。

利用page指令的iserrorpage屬性,就可以把一個jsp頁面變成一個錯誤處理頁面,該屬性必須為true。下面是一個錯誤處理程式。

buggy.jsp

<%@ page errorpage="errorhandler.jsp"%>  

    <%  

        integer.parseint("ee");  

    %>  

errorhandler.jsp

<%@ page language="java" import="java.util.*" pageencoding="utf-8" iserrorpage="true"%>  

<html>  

  <head>  

    <title>error</title>  

  </head>  

  <body>  

    an error has occurred.<br/>  

    error message:  

        out.println(exception.tostring()) ;  

  </body>  

</html>  

如果運作這個buggy.jsp頁面,它就會抛出一個異常。但你不會看到servlet/jsp容器産生的錯誤消息,而是會看到errorhandler.jsp頁面顯示的内容。

jsp實在java中建構web應用程式的第二種技術,作為servlet技術的補充,而不是要取代他。設計得好的java web應用程式一般都會用到servlet和jsp。