首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JSP 轉譯為 Servlet 完整流程深度解析:從源碼到字節碼的生命週期

     編輯:Java 綜合教學

JSP 執行本質:本質上是 Servlet

許多開發者誤以為 JSP 性能遠遜於 Servlet。事實上,首次訪問編譯耗時較長,後續請求直接執行編譯後的 Servlet .class 文件,性能幾乎無差異。Web 容器處理 JSP 請求分四階段:

  1. 客戶端發起 HTTP Request
  2. JSP 容器將 JSP 轉譯為 Servlet 源碼
  3. 編譯源碼為 .class 並加載執行
  4. 輸出 Response 至客戶端

兩個關鍵時期

  • 轉譯時期:JSP → Servlet.java → Servlet.class
  • 請求時期:Servlet 執行響應

容器會檢查 JSP 文件時間戳,若未修改則直接復用已編譯的 Servlet。

實戰演示:showdate.jsp 全流程追蹤

原始 JSP

<%@ page language="java" contentType="text/html;charset=gb2312"
         import="java.text.*,java.util.*;" %>
<html>
<head><title>Show time</title></head>
<body>
Hello :
<%
    SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
    String str = format.format(new Date());
%>
<%=str %>
</body></html>

轉譯後的 Servlet (showdate_jsp.java 關鍵片段)

package org.apache.jsp.ch04;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.text.*;
import java.util.*;

public final class showdate_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

    private static java.util.List _jspx_dependants;

    public void _jspService(HttpServletRequest request, HttpServletResponse response)
            throws java.io.IOException, ServletException {

        JspFactory _jspxFactory = JspFactory.getDefaultFactory();
        PageContext pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true);
        
        ServletContext application = pageContext.getServletContext();
        ServletConfig config = pageContext.getServletConfig();
        HttpSession session = pageContext.getSession();
        JspWriter out = pageContext.getOut();
        Object page = this;

        try {
            response.setContentType("text/html;charset=gb2312");
            
            // 靜態 HTML → out.write()
            out.write("\r\n<html>\r\n<head>\r\n<title>Show time</title>\r\n</head>\r\n<body> \r\n\tHello : \r\n\t");
            
            // JSP 腳本片段 → 直接保留為局部變量聲明
            SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
            String str = format.format(new Date());
            
            // 表達式 <%=str%> → out.print(str)
            out.print(str);
            
            out.write("\r\n</body>\r\n</html>");
        } catch (Throwable t) {
            // 異常處理與頁面錯誤轉發
        } finally {
            _jspxFactory.releasePageContext(pageContext);
        }
    }
}

四大對應關系圖解

JSP 元素Servlet 對應說明
頁面指令 <%@page ...%>response.setContentType()設置響應頭屬性
HTML 靜態模板out.write("...")逐行輸出靜態內容
腳本片段 <% ... %>_jspService 方法體局部變量/語句直接嵌入 Servlet 方法中
表達式 <= ... %>out.print(...)輸出變量值到響應流
聲明 <%! ... %>類成員變量/方法轉為 Servlet 類成員

Servlet 生命周期三方法

public void _jspInit() { }        // 初始化,僅執行一次
public void _jspDestroy() { }     // 銷毀,僅執行一次
public void _jspService(...) { }  // 處理每次請求,核心邏輯在此

性能優化關鍵點

  1. 預編譯:構建階段編譯 JSP,避免首次訪問延遲
  2. 減少腳本片段:優先使用 JSTL/EL 表達式,利於容器優化
  3. 合理設置緩存:<%@ page buffer="16kb" autoFlush="true" %>
  4. 生產環境關閉開發模式:development="false" 禁用文件修改檢查

理解 JSP 到 Servlet 的轉譯機制,不僅能幫助排查運行時錯誤 (如行號對應),更能指導編寫高性能、可維護的視圖層代碼。現代項目建議採用前後端分離架構,JSP 逐步退出歷史舞台。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved