JSP 的注釋和聲明
JSP 腳本
JSP 的三個(gè)編譯指令
JSP 的七個(gè)處理指令
JSP 的九個(gè)內(nèi)置對(duì)象
Servlet 介紹
到自定義標(biāo)簽開發(fā)
使用Filter
使用Li stener
到JSP 2.0 的新特性
JSP是 JavaServerPage 的縮寫,是Servlet 的簡(jiǎn)化。它是由Sun 公司提出的,并由許多公司參與制定的一種動(dòng)態(tài)網(wǎng)頁(yè)標(biāo)準(zhǔn)。其主要特點(diǎn)是在HTML 頁(yè)面中加入Java代碼片段,或者使用各種JSP標(biāo)簽,包括使用用戶標(biāo)簽,構(gòu)成JSP 網(wǎng)頁(yè)。早期使用 JSP 頁(yè)面的用戶非常廣泛,一個(gè)Web應(yīng)用可以全部由JSP 頁(yè)面組成,只輔以少量的 JavaBean 即可。自 J2EE 標(biāo)準(zhǔn)出現(xiàn)以后,人們逐漸認(rèn)識(shí)到使用JSP充當(dāng)過(guò)多的角色是不合適的Q 因此, JSP 慢慢發(fā)展成學(xué)一的表現(xiàn)層技術(shù),不再承擔(dān)業(yè)務(wù)邏輯組件及持久層組件的責(zé)任。
雖然有各種模板技術(shù),但JSP還是最經(jīng)典、應(yīng)用最廣的表現(xiàn)層技術(shù)c
2.1 JSP 的技術(shù)原理
JSP 是 Servlet 的擴(kuò)展,在沒有 JSP 之前,就已經(jīng)出現(xiàn)了 Servlet 技術(shù)。 Servlet 是利用輸出流動(dòng)態(tài)生成 HTML 頁(yè)面,包括每一個(gè) HTML 標(biāo)簽和每個(gè)在 HTML 頁(yè)面中出現(xiàn)的內(nèi)容。
由于包括大量的 HTML 標(biāo)簽、大量的靜態(tài)文本及格式等,導(dǎo)致 Servlet 的開發(fā)效率極為低下。所有的表現(xiàn)邏輯,包括布局、色彩及圖像等,都必須糯合在Java 代碼中,這的確讓人不勝其煩。 JSP 的出現(xiàn)彌補(bǔ)了這種不足, JSP 通過(guò)在標(biāo)準(zhǔn)的 HTML 頁(yè)面中插入Java 代碼,其靜態(tài)的部分無(wú)須 Java 程序控制,只有那些需要從數(shù)據(jù)庫(kù)讀取并根據(jù)程序動(dòng)態(tài)生成信息時(shí),才使用 Java 腳本控制。
從表面上看, JSP 頁(yè)面已經(jīng)不再需要 Java 類,似乎完全脫離了 Java 面向?qū)ο蟮奶卣?。事?shí)上, JSP 是 Servlet 的一種特殊形式,每個(gè) JSP 頁(yè)面就是一個(gè) Se凹let 實(shí)例一-JSP 頁(yè)面由系統(tǒng)編譯成 Servlet, Se凹let 再負(fù)責(zé)響應(yīng)用戶請(qǐng)求。 JSP 其實(shí)也是 Se凹let 的一種簡(jiǎn)化,使用 JSP 時(shí),其實(shí)還是使用 Se凹let,因?yàn)?Web 應(yīng)用中的每個(gè) JSP 頁(yè)面都會(huì)由 Se凹let 容器生成對(duì)應(yīng)的 Servlet。對(duì)于 Tomcat 而言, JSP 頁(yè)面生成的 Se凹let 放在 work 路徑對(duì)應(yīng)的Web 應(yīng)用下。
看下面一個(gè)簡(jiǎn)單的 JSP 頁(yè)面:
〈%for(inti = 0 ; i < 10; i++)
{
out.print1n(i) ;
%>
〈%}%〉
當(dāng)啟動(dòng) Tomcat之后,可以在Tomcat 的 Catalina\localhost\jsptest'飛org飛apache\jsp 目錄下找到如下文件(假如Web應(yīng)用名為jsptest,上面JSP頁(yè)的名為test1扣p):test1.jsp.java和 testtjsp.class。這兩個(gè)文件都是Tomcat 生成的, Tomcat根據(jù) JSP 頁(yè)面生成對(duì)應(yīng) Servlet的 Java文件及 class 文件。
下面是 test1.jsp.java文件的源代碼,這是一個(gè)特殊的Java類,是一個(gè) Serlet類:
//JSP 頁(yè)面經(jīng)過(guò) Tomcat 編譯后默認(rèn)的包
package org.apache.jsp;
import javax.serv1et.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
//繼承 HttpJspBase類,該類其實(shí)是個(gè)Servlet的子類
public final class testl_jsp extends org.apache.
jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent
private staticjava.utiI.Vector_jspx_dependants;
public java.util.List getDependants() {
return _jspx_dependants;
}
//用于響應(yīng)用戶的方法
publicvoid_jspService(HttpServletRequestrequest,
HttpServletResponse response)
throws java.io.IOException, ServletException
//獲得頁(yè)面輸出流
JspFactory_j 日pxFactory= null;
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
//獲得頁(yè)面輸出流
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx-page_context = null;
//開始生成響應(yīng)
try
_jspxFactory = JspFactory.getDefaultFactory();
//設(shè)置輸出的頁(yè)面格式
response.setContentType("text/html; charset=gb2312");
pageContext = _jspxFactory.getPageContext(this, request,
response, null, true, 8192, true);
_jspx-page_context = pageContext;
application = pageContext.getServletContext();
config =pageContext.getServletConfig();
session= pageContext.getSession();
//頁(yè)面輸出流
out =pageCo口text.getOut();
_jspx_out = out;
//輸出流,開始輸出頁(yè)面文襠
out.write("\r\nil) i
//下面輸出 HTML 標(biāo)簽
out.write("4.0TransitionalllEN\">\r\nil) ;
out.write(" \r\丑n);
out.write(" \r\nn) ;
out.write("\r\n") ;
out.write("\r\nil) ;
out.write("\r\nil} ;
//頁(yè)面中的循環(huán),在此處循環(huán)輸出
for(int i = 0 ; i < 10; i++)
out.println(i);
out.write("\r\n") ;
out.write ("
\r\n");
out.write("\r\n");
out.write("c/BODY>\r\n);
out.write("c/HTML>\r\n");
out.write ("\r\n");
}
catch (Throwable t)
{
if(!(t instanceof SkipPageExceptio口))
{
out=_jspx_out;
if (out !=null&& out.getBufferSize()!=0)out.clearBuffer() ;
if (_jspx-page_context!=null)_jspx-page_context.
handlePageException(t);
}
finally
If(_jspxFactory != null)_jspxFactory.releasePageContext(_jspx_
page_context) ;]
}
}
即使讀者不了解上面提供的 Java 代碼,也依然不會(huì)影響 JSP 頁(yè)面的編寫,因?yàn)檫@都是由 Web 容器負(fù)責(zé)生成的。圖 2.1 顯示了 testl.jsp 的執(zhí)行效果。
根據(jù)圖 2.1 的執(zhí)行效果,再次對(duì)比 test1.jsp 和test1-.isp扣va 文件,可得到一個(gè)結(jié)論:該 JSP 頁(yè)面中的每個(gè)字符都由 test1-.isp.java 文件的輸出流生成。圖 2.2 顯示了 JSP 頁(yè)面的i作原理。
圖 2.1 testl.jsp的執(zhí)行效果
根據(jù)上面的 JSP 頁(yè)面i作原理圖,可以得到如下四個(gè)結(jié)論:
JSP文件必須在 JSP服務(wù)器內(nèi)運(yùn)行。
JSP 文件必須生成 Serlet才能執(zhí)行。
每個(gè) JSP 頁(yè)面的第一個(gè)訪問者速度很慢,因?yàn)楸仨毜却?JSP編譯成 Serleta
圖 2.2 JSP 頁(yè)面的i作原理
JSP 頁(yè)面的訪問者無(wú)須安裝任何客戶端,甚至不需要可以運(yùn)行 Java 的運(yùn)行環(huán)境,因?yàn)?JSP 頁(yè)面輸送到客戶端的是標(biāo)準(zhǔn) HTML 頁(yè)面。JSP 的出現(xiàn),大大提高了 Java 動(dòng)態(tài)網(wǎng)站的開發(fā)效率,曾一度風(fēng)靡 JavaWeb 應(yīng)用開發(fā)者。