1.JSP原理分析
我們知道,jsp是動態(tài)資源的一種,它包含HTML代碼,Java腳本以及jsp標(biāo)簽。在
jsp入門中我們了解到,jsp彌補(bǔ)了Servlet和HTML的不足。其實jsp是一種特殊的Servle,后面我們會詳細(xì)介紹。動態(tài)資源不能被瀏覽器直接顯示,需要翻譯成靜態(tài)資源后再發(fā)送給瀏覽器。下面,我們就來了解jsp是如何被翻譯成靜態(tài)資源。
分步驟解析jsp原理,如下所示:
- 當(dāng)瀏覽器第一次訪問jsp頁面時,服務(wù)器會把jsp翻譯成一個Java文件,該Java類是一個Servlet類;
- 然后服務(wù)器再把Java文件編譯成class文件;
- 接著創(chuàng)建該類對象;
- 最后調(diào)用該類的service()方法;
- 當(dāng)?shù)诙卧僭L問該jsp頁面時,直接調(diào)用jsp頁面對應(yīng)Java類的service()方法。
由以上步驟可知,jsp被翻譯成Servlet后,服務(wù)器會為該Servlet類創(chuàng)建對象,并常駐內(nèi)存,當(dāng)服務(wù)器關(guān)閉才銷毀。以后每次訪問該jsp都會調(diào)用該jsp的Servlet類的service()方法。如果jsp頁面被修改,那么再次訪問時,服務(wù)器會重新翻譯該jsp頁面。
下面,通過一張圖來了解第一次訪問jsp頁面的流程圖,如圖1-1所示:
圖1-1 第一次訪問jsp流程圖
2.jsp對應(yīng)Java文件分析
通過以上對jsp原理的理解,我們知道jsp文件會被服務(wù)器翻譯成對應(yīng)的Java文件,下面我們就對jsp對應(yīng)的Java文件進(jìn)行分析。在web應(yīng)用中,對index.jsp進(jìn)行編輯,如例1-1所示:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath= request.getScheme()+"://"+request.getServerName()+":"
+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
This is my JSP page. <br>
<%
int a = 10;
%>
<%
out.print(a++);
%>
<br>
使用Java腳本輸出a的值: <%=a%>
<br>
<%!
int a = 100;
public void fun1() {
System.out.println(a);
}
%>
<%
out.print(this.a++);
fun1();
%>
</body>
</html>
當(dāng)?shù)谝淮卧L問index.jsp后,服務(wù)器會將index.jsp翻譯成對應(yīng)的Java文件,文件名為index_jsp.java。該文件存放的目錄如圖1-2所示:
圖1-2 Java文件所在目錄
由圖1-2可知,jsp編譯后的Java文件都存放在tomcat安裝目錄的work/Catalina/localhos目錄中,其中Example15是項目名稱。
找到文件所在的目錄,點擊此處
查看index_jsp.java文件。下面來分析該文件的代碼,如下所示:
(1)在index.jsp文件中使用<%!%>腳本聲明了成員變量和成員方法,它們在index_jsp.java中的位置如圖1-3所示:
圖1-3 成員所在位置
由圖1-3可知,該java文件的類名就是index_jsp,它繼承了HttpJspBase類,這個類是Tomcat定義的類。該類實現(xiàn)了Servlet接口,因此index_jsp類也是Servlet類。在index_jsp類的成員位置定義了成員變量a,值為100,定義了成員方法fun1()。
(2)接著看index_jsp類的service()方法,如圖1-4所示:
圖1-4 service方法
由圖1-4可知,在index_jsp類中,service()方法的名字是_jspService。我們知道jsp有九大內(nèi)置對象,我們可以由圖1-4看出,在_jspService()方法中,定義了6個變量,分別是session,application,config,out,page,pageContext。由于在_jspService()方法中定義了,因此再jsp頁面中我們可以直接使用這些變量,另外,其他三個內(nèi)置對象:request、response是做為參數(shù)傳遞給了_jspService()方法,exceptionn在后面我們會講解。
(3)每次一請求,服務(wù)器都會調(diào)用_jspService()方法,那么瀏覽器中顯示的頁面信息必然和該放方法有關(guān),下面我們來了解如何將頁面中的信息顯示在瀏覽器,如圖1-5所示:
圖1-5 輸出頁面信息
圖1-5所示中,index.jsp頁面中<%%>里面的代碼在index_jsp.java文件中出現(xiàn)的位置是_jspService()方法中,并且按原樣顯示,而其他的HTML代碼都是以字符串的形式通過out對象調(diào)用write()方法輸出到瀏覽器端。其中:
<base href="<%=basePath%>">
<%= basePath%>被out.print(basePath)方法輸出在瀏覽器端。out對象的writer()方法和print()方法沒有什么區(qū)別,這樣用是為了區(qū)別HTML代碼和Java代碼的輸出。
(4)下面來看在jsp中使用for循環(huán),在index_jsp.java中是如何顯示的,如圖1-6所示:
圖1-6 for循環(huán)
由圖1-6可知,在for循環(huán)中,使用out.write()方法將HTML代碼輸出,對應(yīng)在頁面中的代碼如下所示:
<%
for(int i = 0; i < 10; i++) {
%>
<tr>
<td>張三</td>
<td>29</td>
</tr>
<% } %>
(5)在_jspService()方法中,有一個異常處理,如圖1-7所示:
圖1-7 異常處理
當(dāng)執(zhí)行_jspService()方法過程中,出現(xiàn)了異常,那么圖1-7中的代碼就會捕獲該異常,并進(jìn)行處理。出現(xiàn)異常之前的代碼不會被輸出在瀏覽器端,服務(wù)器會給瀏覽器端響應(yīng)500狀態(tài)碼。并且地址欄地址不變,可以理解為服務(wù)器在做轉(zhuǎn)發(fā),我們知道在進(jìn)行轉(zhuǎn)發(fā)時,response響應(yīng)輸出流中的信息會被清空,因此之前的向response緩沖區(qū)存放的信息不會顯示在瀏覽器端。
本文版權(quán)歸傳智播客Java培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!
作者:傳智播客Java培訓(xùn)學(xué)院
首發(fā):http://xamj520.com/javaee