JSP工作原理


from:http://qing.weibo.com/tj/78edbfd833000h6o.html

      一、歷史

JSP是Servlet的擴展,JSP沒出現之前,就已經出現了Servlet技術.Servlet是利用了"輸出流",動態的生成了HTML頁面。包括 每一個HTML標簽和所有的HTML頁面中出現的內容,簡單點說就是利用Servlet的輸出流將HTML標簽生成一個HTML頁面。由於時間長了 Servlet中包含了大量的HTML標簽、大量的靜態文本及格式等,導致了Servlet的開發效率非常低下.

這時候JSP誕生了,JSP彌補了這種情況,JSP通過在標准的THML頁面中嵌入JAVA代碼,使其靜態的部分無需JAVA程序控制,只有那些需要從數據庫讀取或需要動態生成的頁面內容,才使用JAVA腳本控制。

二、組成

JSP主要是由兩部分組成:

(1)靜態部分:標准的HTML標簽、靜態的頁面內容,這些內容與靜態HTML頁面相同.

(2)動態部分:Java程序控制的內容,這些內容由Java程序來動態生成。

下面是一個最簡單的一段jsp代碼:

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>

<html>

<head>

<title>歡迎</title>

</head>

<body>

歡迎學習Java JSP!現在時間是:<%out.println(new java.util.Date());%>

</body>

</html>

 

頁面中粗體字代碼放在<%和%>之間,表明這些是Java腳本,而不是靜態內容,通過這種方式就可以把Java代碼嵌入HTML頁面中,這就變成了動態的JSP頁面。從表面上來分析,JSP頁面已經不再需要Java類,似乎感覺完全脫離了Java面向對象的特征了,但是,實際上JSP是Servlet的一種特殊的形式,每一個JSP的頁面就是一個Servlet的實例。

為什么是Servlet實例?那是因為你的web項目中每一個JSP頁面,首先都會由Servlet容器生成對應的Servlet類.這個生成好的類放在C:\Program Files\Apache Software Foundation\Tomcat 6.0\work目錄下(注:這里是我自己默認的安裝的目錄)。如果你有過研究的話,你會發現,你部署完你的項目之后,當你啟動了Tomcat之后,你可以在Tomcat的work\Catalina\localhost\你項目名\org\apache\jsp目錄下找到index_jsp.class 和index_jsp.java這兩個文件.其實index_jsp.java是一個特殊的Java類,實際上就是一個Servlet類。

index_jsp.java 這個類間接的繼承了Servlet。仔細看下面的代碼:

//JSP頁面經過Tomcat編譯后默認的包

package org.apache.jsp;

import javax.servlet.*;

import javax.servlet.http.*;

import javax.servlet.jsp.*;

//繼承HttpJspBase類,該類其實是Servlet的子類

public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase

implements org.apache.jasper.runtime.JspSourceDependent {

private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

private static java.util.List _jspx_dependants;

private javax.el.ExpressionFactory _el_expressionfactory;

private org.apache.AnnotationProcessor _jsp_annotationprocessor;

public Object getDependants() {

return _jspx_dependants;

}

public void _jspInit() {

_el_expressionfactory = _jspxFactory.getJspApplicationContext

(getServletConfig().getServletContext()).getExpressionFactory();

_jsp_annotationprocessor = (org.apache.AnnotationProcessor)

getServletConfig().getServletContext().getAttribute(org.apache.

AnnotationProcessor.class.getName());

}

public void _jspDestroy() {

}

//用於響應用戶請求的方法

public void _jspService(HttpServletRequest request, HttpServletResponse response)

throws java.io.IOException, ServletException {

PageContext pageContext = null;

HttpSession session = null;

ServletContext application = null;

ServletConfig config = null;

//定義頁面輸出流

JspWriter out = null;

Object page = this;

JspWriter _jspx_out = null;

PageContext _jspx_page_context = null;

try {

//設置響應格式

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();

//初始化頁面輸出流

out = pageContext.getOut();

_jspx_out = out;

//向頁面輸出內容,下面輸出將會輸出完整的頁面內容

out.write("<!-- 表明這為一個JSP頁面 -->\r\n");

out.write("\r\n");

out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional

//EN\">\r\n");

out.write("<HTML>\r\n");

out.write("<HEAD>\r\n");

out.write("<TITLE>第二個JSP頁面</TITLE>\r\n");

out.write("</HEAD>\r\n");

out.write("<BODY>\r\n");

out.write("<!-- 下面是Java腳本 -->\r\n");

//頁面中的循環,在此處循環輸出

for(int i = 0 ; i < 7; i )

{

out.println("<font size='" i "'>");

out.write("\r\n");

out.write("Java的web世界!)</font>\r\n");

out.write("<br>\r\n");

}

out.write("\r\n");

out.write("</BODY>\r\n");

out.write("</HTML>\r\n");

} catch (Throwable t) {

if (!(t instanceof SkipPageException)){

out = _jspx_out;

if (out != null && out.getBufferSize() != 0)

try { out.clearBuffer(); } catch (java.io.IOException e) {}

if (_jspx_page_context != null) _jspx_page_context.

handlePageException(t);

}

} finally {

_jspxFactory.releasePageContext(_jspx_page_context);

}

}

}
上面的代碼全是WEB容器負責生成的。

三、工作原理

(1)當用戶訪問一個JSP頁面時,回想一個Servlet容器(Tomcat)發出請求;

(2)如果是第一次請求頁面,或頁面有所改動,則servlet容器首先要把JSP頁面(假設為test.jsp)轉化為Servlet代碼(test.java),再將其轉化為(test.class文件);因為這個過程(編譯)會耗費一定時間,所以第一次訪問或jsp文件有改動時,訪問時間有些長;

(3)JSP容器負責調用從JSP轉換來的servlet,這些servlet負責提供服務相應用戶請求(比如客戶端發送表單,要求servlet:formprocessor.java來處理,則容器會建立一個線程,調用formprocessor.java來處理該請求);如果用戶有多個請求,則容器會建立多個線程處理多個請求;

(4)容器執行字節碼文件(包括調用的servlet:formprocessor.java字節嗎),並將其結果返回到客戶端;(返回的最終方式是有servlet輸出html格式的文件流)

注釋:

JSP頁面必須要在JSP服務器內運行,如tomcat weblogic,jboss等等.(順便說一下,apache 和 tomcat是兩碼事兒,有不少人認為
apache就是tomcat,其實是錯誤的理解!~,tomcat只是apache中的一個子項目,apache是作為WEB應用服務器,而tomcat可以說是JSP或
Servlet的一個web容器);
JSP頁面的訪問者無須安裝任何客戶端,甚至不需要可以運行Java的運行環境,因為JSP頁面輸送到客戶端的是標准HTML頁面。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM