最近老是失眠,還好我靈雞一動,學習了jsp(得勁)。
Jsp和Servlet的本質是一樣的,Jsp最終被編譯成Servle才能運行,或者說jsp只是生成Servlet的草稿文件。
Jsp特點就是在HTML中嵌入java代碼,或者使用各種Jsp標簽,包括自定義標簽,動態的提供頁面內容,現在發展為表現層技術。
(其他表現層的技術:FreeMarker,Velocity,Tapestry等,其中Jsp應用最為廣泛)
Jsp的本質是Servlet。Jsp頁面由兩部分組成:
靜態部分:標准的HTMl標簽,靜態的頁面內容,與HTML頁面相同
動態部分:受Java代碼控制的內容,這些內容由java腳本動態生成
Jsp變異之后會變成Servletjava代碼,比如原本一個叫zpoor.jsp,編譯之后就變成了zpoor_jsp.java和zpoor_jsp.class文件,Tomcat的work下的localhost文件夾中編譯之后的代碼。
Jsp工作原理結論:
Jsp文件必須在jsp服務器內運行。
每個Jsp文件都必須生成Servlet才能執行
每個Jsp頁面的第一個訪問者速度很慢,因為必須等待Jsp編譯成Servlet
Jsp頁面的訪問者無需安裝任何客戶端,不需要安裝可以運行java的環境,因為Jsp頁面輸出的標准的HTMl頁面
Jsp注釋:(源代碼看不到)
<%-- 注釋內容 --%>
HTML注釋:(源代碼可以看到)
<!-- 注釋內容 -->
Jsp聲明:(聲明變量和方法:當然他自然會裝換成Servlet的成員變量和成員方法,Jsp聲明依然符合java語法)
<%! 聲明部分 %>
注意:jsp聲明定義的方法和變量可以使用private 、public修飾符也可以使用static,將其變成類屬性或者類方法,但是不能使用
abstract修飾部分的方法,因為抽象方法會導致Jsp對應Servlet變成抽象類,倒置無法實例化。
(Jsp中聲明中獨立存在的方法,知識一種假象)
Jsp輸出表達式:
<%= 表達式 %>
輸出表達式語法后面不能有分號
Jsp的3個編譯指令:
page:該指令是針對當前頁面的指令
include:用於指定包含另一個頁面
taglib:用於定義和訪問自定義標簽(Jsp新特性)
語法:
<%@ 編譯指令名 屬性名="屬性值"%>
page指令(一般位於Jsp頁面的頂端,一個Jsp可以包含多個page指令):
language:聲明腳本語言類型,一般是java,只能是java
extends:指定jsp頁面編譯之后所產生的java類所繼承的父類或者接口
import:用來導入包
session:jsp頁面是否需要HttpSession
buffer:指定jsp頁面的緩沖區的大小,默認值為8kb
autoFlush:緩沖區溢出時,是否強制輸出緩沖區的內容
info:設置該jsp程序的信息
errorPage:指定錯誤處理界面
isErrorPage:設置本jsp程序是否為錯誤處理程序
pageEncoding:設置生成網頁的字符集編碼
include指令:
把一個外部文件嵌入當前的jsp頁面中,同時解析這個頁面的Jsp語句,這是靜態include語句,他會把目標頁面的其他編譯指令也包含進來如果兩個頁面的編譯指令沖突,頁面就會出錯,但是動態的include則不會。
語法<%@ include file="文件路徑/文件名"%>
Jsp的7個動作指令:
編譯指令是通知Servlet引擎處理消息
動作指令知識運行時的動作
jsp:forward:執行頁面轉向,將請求的處理轉發到下一個頁面
jsp:param:傳遞參數,必須和其他支持參數的標簽一起使用
jsp:include:動態的引入一個jsp頁面
jsp:plugin:下載javaBean和Applet到客戶端執行
jsp:useBean:創建一個useBean的實例
jsp:setProperty:設置javaBean實例的屬性值
jsp:getProperty:輸出javaBean實例的屬性值
forward指令:
將頁面的請求轉發到一個新的頁面,可以是靜態的HTML頁面,也可以是動態的jsp頁面,或者轉發到容器中的Servlet
語法:
對於jsp1.0:
<jsp:forward page="URL">
對於jsp1.1:(用於轉發時增加額外的請求參數)
<jsp: forward page="URL">
<jsp:param.../>
</jsp:forward>
注意:
執行forward指令轉發請求時,客戶端的請求參數不會丟失。表面上他是將用戶請求轉發到另一個新的頁面,實際上知識采用了新的界面來對用戶生成相應,所以說,請求還是一次請求,作用請求參數和請求屬性都不會改變。
include指令:
他是一種動態的include指令,用於包含某個頁面,他不會導入被include頁面的編譯指令,只導入頁面的body內容插入本頁面。
語法(常用):
<jsp:include page="URL" flush="true|false">
<jsp:param.../>
</jsp:include>
其中flush屬性:指定輸出緩存是否轉移到被導入的文件中,如果為true,則包含在被導入的文件中,如果為false,則包含在原文件中。
靜態導入和動態導入的三個區別:
1、靜態導入是將被導入頁面的代碼完全融合,兩個頁面融合成一個整體的Servlet;動態導入則在Servlet中使用include方法來引入被導入的頁
面的內容。
2、靜態導入時,被導入的頁面的編譯指令會產生作用;動態導入時被導入的編譯指令則會失去作用,只是插入被導入頁面的body內容
3、動態導入還可以增加額外的參數
forward動作指令和include動作指令的區別:
執行forward時,被forward的頁面將完全代替原有頁面,執行include時,被include的頁面知識插入原有的頁面
一句話:forward拿目標頁面代替原有頁面,include則拿目標頁面插入原有的頁面。
useBean、setProperty、getProperty指令:
三個指令都是與javaBean相關的指令
useBean語法:
<jsp:useBean id="name" class="classname" scope="page|request|session|application"/>
id屬性就是Javabean的實例名,class屬性確定了JavaBean的實現類
scope屬性指定javaBean市里的作用范圍:
page:該javaBean實例只在該頁面有效
request:在本次請求內有效
session:在本次session內有效
application:在本應用內一直有效
(下面的兩個標簽的底層實現還是基於getter和setter方法實現)
setProperty(語法):
<jsp:setProperty name="BeanName" property="propertyName" value="value"/>
name屬性確定了javaBean的實例名;property屬性確定需要設置的屬性名;value屬性則確定需要設置的屬性值
getPeoperty(語法) :
<jsp:getProperty name="BeanName" property="propertyName"/>
name屬性確定了需要輸出的javaBean的實例名;property屬性確定需要輸出的屬性名。
把JavaBean放在指定的scope中:
//放在page范圍中
pageContext.setAttribute("p1", p1);
//放在request范圍中
request.setAttribute("p1", p1);
//放在session范圍中
session.setAttribute("p1", p1);
//放在application范圍中
application.setAttribute("p1", p1);
plugin指令:
主要用於下載服務端的javaBean或者Applet到客戶端執行,客戶端必須裝虛擬雞(嘿嘿嘿)。
當然這玩意用的很少,現在HTML對Applet的支持很好,基本上用不到這個動作指令。
param指令:
用於設置參數值,本身不能單獨使用,沒有什么意義。
一般都結合下面的三個指令使用:
1、jsp:include
param指令把參數傳入被導入的頁面
2、jsp:forward
param指令把參數傳向被轉入的頁面
3、jsp:plugin
param指令把參數傳入頁面中的javabean或者Applet