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

JSP 架構與執行流程

     編輯:JSP 入門

JSP 架構與執行流程

JSP 運行需要支援 Servlet/JSP 規格的 Web 容器 (如 Tomcat、Jetty、WildFly)。理解架構與請求流程有助於效能調優、除錯與架構決策。


核心組件

組件角色代表實作
Web Server處理靜態資源、SSL 終結、負載平衡、反向代理Nginx, Apache HTTPD, IIS
Servlet Container (JSP Engine)管理 Servlet/JSP 生命週期、請求分派、會話、安全Tomcat, Jetty, Undertow
JSP Translator/Compiler將 .jsp 翻譯為 .java 再編譯為 .classJasper (Tomcat), JspC
Class Loader載入 JSP 生成的 Servlet 類別、應用類別、庫WebappClassLoader
Session Manager建立/儲存/復原 HttpSession (記憶體/檔案/資料庫/Redis)StandardManager, PersistentManager

JSP 請求處理完整流程 (7 步驟)

  1. 瀏覽器發送 HTTP 請求:GET /app/page.jsp HTTP/1.1
  2. Web Server 接收:靜態資源直接回應;動態請求 (如 *.jsp) 轉發給 Servlet Container (AJP/HTTP)
  3. Container 映射 Servlet:JspServlet (內建) 處理 *.jsp 路徑
  4. 檢查/執行翻譯編譯:
    • 對應 .class 存在且 .jsp 未修改 → 直接載入
    • 否則:解析 JSP → 生成 Java → 編譯 → 載入類別
  5. 建立/取得 Servlet 實例:單例模式,首次建立呼叫 jspInit()
  6. 建立隱含物件並呼叫 _jspService(req, resp):
    • PageContext、request、response、session、application、config、out、page、exception
    • 執行模板文字輸出、Scriptlet、Expression、動作元素
  7. 回應提交給客戶端:Container 將回應標頭、主體透過 Web Server 送回瀏覽器

流程圖 (文字版)

[Browser] 
   │ HTTP Request
   ▼
[Web Server: Nginx/Apache] ──靜態資源──► [Browser]
   │ 動態請求 (*.jsp)
   ▼ (Proxy Pass / AJP)
[Tomcat: Coyote Connector] 
   │
   ▼
[Mapper: JspServlet (/*.jsp)]
   │
   ▼
[JSP Compiler: Jasper] ──首次/修改──► [.jsp] → [.java] → [.class]
   │                              已編譯/未修改 ──► [Class Loader]
   ▼
[JSP Servlet Instance] (Singleton)
   │
   ├── jspInit() (首次)
   │
   ▼
[_jspService(req, resp)] ◄─── 每次請求
   │
   ├── PageContext, Request, Response, Session, Application, Out, ...
   │
   ▼
[Template Text + Scriptlet + Expression + Actions] → out.write/print
   │
   ▼
[Response Committed] → Coyote → Web Server → Browser

關鍵效能點

環節優化方向
靜態資源Nginx 直接服務,啟用快取、GZIP、HTTP/2
JSP 編譯生產環境預編譯 (jspc),關閉開發模式 (development=false)
Session 儲存高併發改用 Redis (Spring Session),避免記憶體/檔案瓶頸
資料庫連線連線池 (HikariCP),JNDI DataSource
模板渲染複雜頁面改用 Thymeleaf/FreeMarker,或前後端分離 (REST + Vue/React)
類別載入避免熱部署類別洩漏,生產環境完整重啟

Tomcat 目錄結構與 JSP 相關

tomcat/
├─ bin/              啟動/關閉腳本
├─ conf/
│  ├─ server.xml     連接器、引擎、主機、Context 設定
│  ├─ web.xml        全域 Servlet 映射 (含 JspServlet)
│  └─ context.xml    全域 Context 參數
├─ lib/              共享庫 (servlet-api, jsp-api, jdbc drivers)
├─ webapps/          應用部署目錄
│  └─ ROOT/          預設應用
│     ├─ WEB-INF/
│     │  ├─ web.xml       應用部署描述
│     │  ├─ classes/      應用類別
│     │  ├─ lib/          應用專用 JAR
│     │  └─ *.tld         標籤庫描述
│     ├─ *.jsp            JSP 頁面
│     └─ static/          靜態資源
├─ work/
│  └─ Catalina/localhost/_/org/apache/jsp/  JSP 編譯產生的 .java/.class
└─ logs/             存取日誌、催化日誌

部署模式

模式說明優點缺點
獨立 Tomcat單一 JVM 運行 Container + App簡單、資源共享單點故障、擴展受限
Nginx + Tomcat 叢集Nginx 負載平衡分發至多 Tomcat高可用、水平擴展Session 需外部化 (Redis)
Docker/K8s 容器化映像打包 App + Tomcat,K8s 編排彈性擴縮、滾動更新、隔離運維複雜度較高
前後端分離JSP 退役,改 REST API + 前端框架關注點分離、體驗佳、技術棧靈活SEO 需 SSR、雙端開發成本

常見問題與診斷

  1. 修改 JSP 不生效:檢查 work 目錄是否殘留舊編譯檔、Tomcat development 參數、瀏覽器/Proxy 快取
  2. 中文亂碼:URIEncoding="UTF-8"、pageEncoding、request.setCharacterEncoding、資料庫連線編碼
  3. 類別衝突:WEB-INF/lib 版本與 tomcat/lib 衝突 (如 servlet-api, jstl)
  4. 記憶體洩漏:ThreadLocal 未清理、JDBC 驅動未註銷、靜態集合持有請求物件 → 使用 Matthews / VisualVM 分析
  5. JSP 編譯錯誤:查看 work/.../org/apache/jsp/ 下生成的 .java 定位行號

現代化演進建議

  1. 新專案採用 Spring Boot + Thymeleaf/FreeMarker:內嵌容器、自動配置、模板引擎功能更強
  2. 微服務架構:JSP 單體應用拆分為 REST API 服務 + 前端獨立部署
  3. Serverless:函數計算 (AWS Lambda, Azure Functions) 運行 Java 函數,無容器管理
  4. GraalVM Native Image:Java 應用編譯為原生執行檔,啟動極快、記憶體低
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved