不依賴 IDE,使用 JDK + Tomcat 手動建置 JSP 開發環境,適合伺服器部署、CI/CD、輕量級開發、教學理解底層運作。
# Ubuntu/Debian sudo apt update && sudo apt install openjdk-17-jdk # CentOS/RHEL/Fedora sudo dnf install java-17-openjdk-devel # macOS (Homebrew) brew install openjdk@17 # 設定路徑 (視 shell) echo 'export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"' >> ~/.zshrc
JAVA_HOME = C:\Program Files\Eclipse Adoptium\jdk-17.x.x-hotspotPath 新增 %JAVA_HOME%\binjava -version; javac -version# Linux/macOS tar -xzf apache-tomcat-10.1.x.tar.gz -C /opt/ ln -s /opt/apache-tomcat-10.1.x /opt/tomcat # Windows # 解壓至 D:\tomcat
tomcat/ ├─ bin/ startup.sh/bat, shutdown.sh/bat, catalina.sh/bat ├─ conf/ │ ├─ server.xml 核心設定 (Port, Host, Context, Valve) │ ├─ web.xml 全域 Servlet 映射 │ ├─ context.xml 全域 Context 參數 │ └─ tomcat-users.xml 管理員帳號 ├─ lib/ 共享庫 (servlet-api.jar, jsp-api.jar, ...) ├─ webapps/ 應用部署目錄 (ROOT/, manager/, host-manager/) ├─ work/ JSP 編譯輸出 (.java, .class) ├─ logs/ catalina.out, localhost_access_log, ... └─ temp/ 臨時檔案
# Linux/macOS ~/.bashrc / ~/.zshrc export CATALINA_HOME=/opt/tomcat export PATH=$CATALINA_HOME/bin:$PATH # Windows 系統變數 CATALINA_HOME = D:\tomcat Path 追加 %CATALINA_HOME%\bin
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Service name="Catalina">
<!-- HTTP/1.1 Connector -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8" /> <!-- 關鍵:GET 參數 UTF-8 -->
<!-- AJP Connector (給 Nginx/Apache 反向代理) -->
<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
<!-- conf/tomcat-users.xml --> <role rolename="manager-gui"/> <role rolename="admin-gui"/> <user username="admin" password="securePassword" roles="manager-gui,admin-gui"/>
# 啟動 (前景) startup.sh # Linux/macOS startup.bat # Windows # 背景啟動 catalina.sh start # Linux/macOS # Windows 無原生背景模式,可用服務或 NSSM # 關閉 shutdown.sh shutdown.bat # 驗證 curl https://localhost:8080/ # 瀏覽器開啟 https://localhost:8080/ 應顯示 Tomcat 首頁
# 專案結構 myapp/ ├─ index.jsp ├─ WEB-INF/ │ ├─ web.xml (可選) │ └─ lib/ (第三方 JAR) # 複製 cp -r myapp $CATALINA_HOME/webapps/ # 或建立連結 (開發便利) ln -s /path/to/myapp $CATALINA_HOME/webapps/myapp
# 打包 cd myapp jar -cvf ../myapp.war * # 部署 cp myapp.war $CATALINA_HOME/webapps/ # Tomcat 自動解壓 (unpackWARs=true)
<!-- $CATALINA_HOME/conf/Catalina/localhost/myapp.xml --> <Context docBase="/opt/apps/myapp" path="/myapp" reloadable="true" />
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %> <!DOCTYPE html> <html><body> <h1>手動部署 JSP 測試</h1> <p>時間:<%= new java.util.Date() %></p> </body></html>
儲存為 $CATALINA_HOME/webapps/myapp/index.jsp,瀏覽器訪問 https://localhost:8080/myapp/,Tomcat 自動翻譯編譯。
# MyServlet.java
package com.example;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.*;
@WebServlet("/hello")
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().println("Hello from Servlet!");
}
}
# 編譯 (需 servlet-api.jar) mkdir -p WEB-INF/classes javac -cp "$CATALINA_HOME/lib/servlet-api.jar" -d WEB-INF/classes MyServlet.java # 部署結構 myapp/ ├─ WEB-INF/ │ ├─ classes/com/example/MyServlet.class │ └─ web.xml (若不使用 @WebServlet) └─ index.jsp
# Maven mvn clean package # 產生 target/*.war → 複製到 webapps/ 或 Context docBase
編譯 Servlet/JSP 相關類別時需包含 Servlet API:
# Linux/macOS export CLASSPATH=$CATALINA_HOME/lib/servlet-api.jar:$CATALINA_HOME/lib/jsp-api.jar:. # Windows set CLASSPATH=%CATALINA_HOME%\lib\servlet-api.jar;%CATALINA_HOME%\lib\jsp-api.jar;.
注意:執行 Tomcat 時 不要 設定 CLASSPATH,Tomcat 內建類別載入器會自動管理。
| 現象 | 可能原因 | 檢查/解決 |
|---|---|---|
| 啟動失敗 Port 已佔用 | 8080 被其他程式使用 | lsof -i:8080 / netstat -ano | findstr 8080 找 PID kill |
| 404 Not Found | Context Path 錯誤、應用未部署、web.xml 映射錯誤 | 檢查 webapps/ 目錄、server.xml Host appBase、Context path |
| JSP 編譯錯誤 | 語法錯誤、缺少標籤庫、JDK 版本不符 | 查看 work/.../org/apache/jsp/ 下 .java 檔案行號、logs/catalina.out |
| 中文亂碼 | 編碼鏈路不一致 | Connector URIEncoding、pageEncoding、request.setCharacterEncoding、DB URL characterEncoding |
| Session 失效/不共享 | 叢集無 Session 複寫、Cookie Domain/Path 錯誤 | 配置 Redis Session (Spring Session)、檢查 Cookie 設定 |
| 靜態資源 404 | DefaultServlet 映射、資源路徑錯誤 | 確認 web.xml <servlet-mapping> default / </servlet-mapping>、資源放在 webapp 根目錄 |
webapps/docs, examples, manager, host-managerautoDeploy="false" deployOnStartup="false"CATALINA_OPTS="-Xms2g -Xmx4g -XX:+UseG1GC -Dfile.encoding=UTF-8"server.xml SSL Connector、導入憑證AccessLogValve + ELK/Fluentdlogrotate、cron 備份 webapps/、資料庫