Java Servlet 並不屬於 Java SE(Standard Edition),它是一種擴充套件,稱為 Jakarta EE,專門用於處理 Web 應用相關的需求。要使用 Servlet 功能,必須透過支援 Java EE 的 Web 容器,例如 Tomcat、Jetty 或 GlassFish,這些容器會內建提供所需的 Servlet API。
若不使用這些容器,也可以手動引入相應的 JAR 檔(如 jakarta.servlet-api.jar),即可在專案中使用 Servlet 技術。
PHP、Python Web、Java Web
php
在 PHP 的網頁開發中,除了可撰寫純 .html 的靜態頁面外,也常使用 .php 副檔名來建立動態網頁。.php 檔案會由 PHP 伺服器解析並執行內部的程式碼,最後輸出成 HTML 格式,傳送至用戶端瀏覽器顯示。 .php 檔案本質上是 HTML 文件中嵌入 PHP 程式碼的結合體。PHP 程式區塊通常以 <?php …. ?> 作為標記,用來分隔 HTML 與 PHP 程式碼。PHP 的語法與 C 語言相似,這種將程式邏輯與畫面結合的寫法,在大型專案中可能會導致程式碼結構混亂,維護上較為困難。
Python Web
在 Python 的 Web 框架中,Django 是目前較為普及的套件。Django 不是 Web Server,它只是一個框架。可以讓開發者能以純 Python 撰寫後端邏輯、模板以及靜態 HTML 頁面。 Django 的模板系統類似於 PHP 的作法,允許在 HTML 中嵌入特定的模板語法,以便與後端 Python 程式碼進行資料傳遞與渲染,扮演 Python 與 HTML 之間的溝通橋樑。 不過 Django 的模板語法較為受限與不便,盡量少用。
Python Web 是目前超流行的框架,因為有關 AI 的應用都是以 Python 開發。所以要製作有關 AI 的網站,Python Web 是最佳選擇。
Java Web
在 Java Web 開發中,常見的做法是使用 Tomcat 作為 Web Server,再透過 Servlet 技術撰寫純 Java 的後端程式碼。JSP(JavaServer Pages)則是一種嵌入於 HTML 中的語法,用來與後端進行資料交換與畫面呈現,其概念類似於 Python 的模板引擎。 早期 JSP 曾被視為有潛力取代 PHP 的技術,因為它同時具備動態內容與 Java 的穩定性。然而,隨著專案規模增長,JSP 的頁面往往容易變得雜亂,將商業邏輯與畫面混在一起,導致程式碼難以維護。因此在後來的開發實務中,越來越多開發者轉向使用 Servlet 或其他更具架構化的 MVC 框架,如 Spring MVC,以達到更好的模組分離與可維護性。
MySQL 連線
JDBC 驅動
請先到 MySQL 官網 https://dev.mysql.com/downloads/connector/j/ 下載最新版本的驅動程式,Operating System 請選取 Platform Independent,然後再選取 zip 檔。

下載完成後請將 zip 檔解開,在 NetBeans 的 Libraries 按右鍵 Add JAR/Folder,然後選定 mysql-connector-j-8.4.0.jar,當執行編譯時,此 .jar 會自動複製到專案下的 build\web\WEB-INF\lib 之下。
WEB-INF\lib 日後會手動複製到 Tomcat docBase 目錄下,所以不需要再複製到系統級的 C:\Program Files\Apache Software Foundation\Tomcat 11.0\lib。但如果是在 JSP 網頁使用資料庫連線,還是需要手動複製一份到 Tomcat 11.0\lib。
Servlet 網頁
撰寫 Servlet 網頁時,有幾個坑要避開。
手動輸入 java.sql
NetBeans 有 Bug,需手動在程式碼中輸入如下
import java.sql.*
載入驅動程式
Java 6 開始不用手動載入驅動程式,但在 Servlet 還是需要手動載入驅動程式,如下所示。
try{
Class.forName("com.mysql.cj.jdbc.Driver");
}
catch (ClassNotFoundException ex){
out.println(ex.toString());
}
完整代碼
請新增一個 Servlet 網頁,輸入如下完整的代碼
package net.ddns.mahaljsp; import java.sql.*; import java.io.IOException; import java.io.PrintWriter; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @WebServlet(name = "index", urlPatterns = {"/index"}) public class index extends HttpServlet { protected void processRequest( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); String url="jdbc:mysql://ip/cloud"; String user="帳號"; String password="密碼"; PreparedStatement stmt; ResultSet rs; try (PrintWriter out = response.getWriter()) { try{ Class.forName("com.mysql.cj.jdbc.Driver"); try(Connection conn=DriverManager.getConnection(url,user,password)){ stmt=conn.prepareStatement("select * from 台灣股市"); rs=stmt.executeQuery(); out.println("<html>"); out.println("<head>"); out.println("<title>MySQL連線</title>"); out.println("</head>"); out.println("<body>"); out.println( "<table border='1' cellspacing='0' cellpadding='0' width='300'" ); while(rs.next()){ out.println("<tr>"); out.printf("<td>%s</td><td>%s</td><td>%s</td>", rs.getString(2), rs.getString(3), rs.getString(6) ); out.println("</tr>"); } out.println("</table>"); out.println("</body>"); out.println("</html>"); } catch (SQLException ex) { out.print(ex.toString()); } } catch(ClassNotFoundException ex){ out.println(ex.toString()); } } } }
JSP網頁
底下是使用 jsp 網頁的寫法。
<body>
<%!
String user = "student";
String pass = "1234";
String db = "travel";
String url = String.format(
"jdbc:mysql://localhost:3306/%s?useUnicode=true&characterEncoding=UTF-8",
db);
Connection conn;
Statement stmt;
%>
<%
try{
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection(url,user,pass);
}
catch(SQLException e){
out.println("SQL Exception : " + e);
}
%>
<table border="1" cellpadding="0" cellspacing="0">
<%
//顯示資料庫內容
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from member");
while (rs.next()) {
out.println("<tr>");
out.println(String.format("<td>%s</td><td>%s</td><td>%s</td>",
rs.getString(2),
rs.getString(3),
rs.getString(4)));
out.println("</tr>");
}
%>
</table>
</body>
會員登入系統
Servlet 的運作方式如果用文字描述,一大篇文章也寫不完,直接實作會員登入系統看程式碼是最為快速的方法。
會員登入系統分為登入表單 (login.jsp),登入處理程式 (login.java),即登入成功畫面 (welcome.jsp)。
login.jsp
首先在專案按右鍵/New/JSP,File Name 輸入 login,完整代碼如下。
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head><title>登入系統</title></head>
<style>
table{
margin:0px auto;
width:250px;
border:1px solid;
border-collapse:collapse;
font-size:16px;
}
tr{
border:1px solid;
}
td{
border:1px solid;
}
</style>
<body>
<form method="post" action="login">
<table>
<tr>
<td colspan=2" style="text-align:center;">會員登入系統</td>
</tr>
<tr>
<td>帳號</td>
<td>
<input type="text" name="userAccount"/>
</td>
</tr>
<tr>
<td>密碼</td>
<td>
<input type="password" name="userPassword"/>
</td>
</tr>
<tr>
<td colspan="2" style="text-align:center;">
<input type="submit" value="登入">
</td>
</tr>
</table>
</form>
<p style="color:red;">${error}</p>
</body>
</html>
上述表單 action 屬性會跳到 /login 網頁,此為 Servlet 網頁。
Login.java
在專案下按「右鍵/New/Servlet」,Class Name 輸入 login,完整代碼如下。
package net.ddns.mahaljsp;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.PrintWriter;
import java.sql.*;
@WebServlet(name = "login", urlPatterns = {"/login"})
public class login extends HttpServlet {
@Override
protected void doGet(
HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
@Override
protected void doPost(
HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
boolean isValid=false;
String userAccount=request.getParameter("userAccount");
String userPassword=request.getParameter("userPassword");
try {
Class.forName("com.mysql.cj.jdbc.Driver");
try(Connection conn=DriverManager.getConnection(
G.dbUrl,G.dbUser, G.dbPassword)) {
String cmd="select * from 會員資料 where userAccount=? and userPassword=?";
PreparedStatement ps=conn.prepareStatement(cmd);
ps.setString(1, userAccount);
ps.setString(2, userPassword);
ResultSet rs=ps.executeQuery();
if (rs.next())isValid=true;
}
catch(SQLException ex){}
if(isValid){
HttpSession session=request.getSession();
session.setAttribute("user", userAccount);
response.sendRedirect("welcome.jsp");
}
else{
response.getWriter().println("帳密錯誤");
}
}
catch (ClassNotFoundException ex) {}
}
@Override
public String getServletInfo() {
return "Short description";
}
}
session 是記錄登入者的帳號,而 response.sendRedirect 則是跳轉其它網頁。
welcome.jsp
因為上述 login.java 如果登入成功會自動轉跳 welcome.jsp,所以就隨意寫個測試程式,代碼如下
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>歡迎光臨</h1>
</body>
</html>
