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

Eclipse + Tomcat 從零搭建 Web 登錄頁面完整教程

     編輯:Java 相關知識

環境準備清單

在開始之前,請確保已完成以下基礎環境配置:

組件推薦版本下載地址
JDK17 LTS / 21 LTSAdoptium Temurin
Eclipse IDE2023-12 / 2024-03Eclipse Downloads (選 Eclipse IDE for Enterprise Java Developers)
Apache Tomcat10.1.x (Servlet 6.0) / 9.0.x (Servlet 4.0)Tomcat Downloads
MySQL (可選)8.0 LTSMySQL Downloads

JDK 環境變量配置 (Windows)

  1. 安裝 JDK 至無中文路徑目錄,如 D:\Java\jdk-21
  2. 右鍵「此電腦」→ 屬性 → 高級系統設置 → 環境變量
  3. 系統變量新建:
    • JAVA_HOME = D:\Java\jdk-21
    • CLASSPATH = .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
  4. 編輯 Path,添加 %JAVA_HOME%\bin 和 %JAVA_HOME%\jre\bin
  5. 驗證:CMD 執行 java -version、javac -version

Eclipse 整合 Tomcat

  1. Eclipse 菜單 Window → Preferences → Server → Runtime Environments
  2. 點擊 Add...,選擇對應 Tomcat 版本 (如 Apache Tomcat v10.1)
  3. Browse 選擇 Tomcat 安裝目錄 (如 D:\Java\apache-tomcat-10.1.20),JRE 選擇已配置的 JDK
  4. Finish 完成

創建動態 Web 專案

  1. File → New → Dynamic Web Project
  2. Project name: LoginDemo
  3. Target runtime: 選擇剛配置的 Tomcat
  4. Dynamic web module version: 6.0 (Tomcat 10) 或 4.0 (Tomcat 9)
  5. Configuration: 默認即可
  6. Finish (若提示打開 Web 透視圖選 Yes)

解決專案編碼與依賴問題

右鍵專案 → Properties → Web Project Settings → 將 Default encoding 改為 UTF-8。
若 web.xml 報錯,右鍵專案 → Build Path → Configure Build Path → Libraries → Add Library → Server Runtime → 選擇 Tomcat → Apply and Close。

登錄頁面開發實戰

1. 準備靜態資源

在 WebContent 下創建目錄結構:

WebContent/
├── css/
│   └── login.css
├── images/
│   ├── logo.png
│   └── bg.jpg
└── js/
    └── validate.js

2. login.jsp - 登錄頁面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>用戶登錄</title>
    <link rel="stylesheet" href="css/login.css">
</head>
<body>
    <div class="login-container">
        <div class="login-box">
            <h2>系統登錄</h2>
            <form action="LoginServlet" method="post" id="loginForm">
                <div class="form-group">
                    <label>用戶名</label>
                    <input type="text" name="username" id="username" required autocomplete="username">
                </div>
                <div class="form-group">
                    <label>密碼</label>
                    <input type="password" name="password" id="password" required autocomplete="current-password">
                </div>
                <div class="form-group captcha-group">
                    <label>驗證碼</label>
                    <div class="captcha-input">
                        <input type="text" name="captcha" id="captcha" maxlength="4" required>
                        <img src="CaptchaServlet" id="captchaImg" alt="點擊刷新" title="點擊刷新驗證碼">
                    </div>
                </div>
                <button type="submit" class="btn-login">登錄</button>
            </form>
        </div>
    </div>
    <script src="js/validate.js"></script>
</body>
</html>

3. login.css - 現代化樣式

* { box-sizing: border-box; margin: 0; padding: 0; }
body {
    font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}
.login-container { width: 100%; max-width: 400px; padding: 20px; }
.login-box {
    background: white;
    border-radius: 12px;
    box-shadow: 0 20px 60px rgba(0,0,0,0.15);
    padding: 40px;
}
.login-box h2 { text-align: center; color: #333; margin-bottom: 30px; font-weight: 600; }
.form-group { margin-bottom: 20px; }
.form-group label { display: block; margin-bottom: 8px; color: #666; font-size: 14px; }
.form-group input {
    width: 100%;
    padding: 12px 15px;
    border: 1px solid #ddd;
    border-radius: 6px;
    font-size: 16px;
    transition: border-color 0.3s, box-shadow 0.3s;
}
.form-group input:focus {
    outline: none;
    border-color: #667eea;
    box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.15);
}
.captcha-group .captcha-input { display: flex; gap: 10px; }
.captcha-group input { flex: 1; }
.captcha-group img { height: 46px; cursor: pointer; border-radius: 6px; border: 1px solid #eee; }
.btn-login {
    width: 100%;
    padding: 14px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    border: none;
    border-radius: 6px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.2s, box-shadow 0.2s;
}
.btn-login:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4); }
.btn-login:active { transform: translateY(0); }

4. validate.js - 前端校驗與驗證碼刷新

document.addEventListener('DOMContentLoaded', () => {
    const form = document.getElementById('loginForm');
    const captchaImg = document.getElementById('captchaImg');
    
    // 點擊驗證碼圖片刷新
    captchaImg.addEventListener('click', () => {
        captchaImg.src = 'CaptchaServlet?' + Date.now();
    });
    
    // 表單提交前驗證
    form.addEventListener('submit', (e) => {
        const username = document.getElementById('username').value.trim();
        const password = document.getElementById('password').value;
        const captcha = document.getElementById('captcha').value.trim();
        
        if (!username || !password || !captcha) {
            e.preventDefault();
            alert('請填寫所有字段');
            return;
        }
        if (captcha.length !== 4) {
            e.preventDefault();
            alert('驗證碼為 4 位字符');
        }
    });
});

後端 Servlet 實現

1. 驗證碼生成 Servlet

@WebServlet("/CaptchaServlet")
public class CaptchaServlet extends HttpServlet {
    private static final String CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
    private static final int WIDTH = 100, HEIGHT = 40, LENGTH = 4;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 生成驗證碼
        StringBuilder sb = new StringBuilder();
        Random rand = new Random();
        for (int i = 0; i < LENGTH; i++) {
            sb.append(CHARS.charAt(rand.nextInt(CHARS.length())));
        }
        String code = sb.toString();
        
        // 存入 Session
        req.getSession().setAttribute("captcha", code.toLowerCase());
        
        // 繪製圖片
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(new Color(240, 240, 240));
        g2d.fillRect(0, 0, WIDTH, HEIGHT);
        
        // 干擾線
        g2d.setColor(new Color(200, 200, 200));
        for (int i = 0; i < 5; i++) {
            g2d.drawLine(rand.nextInt(WIDTH), rand.nextInt(HEIGHT), rand.nextInt(WIDTH), rand.nextInt(HEIGHT));
        }
        
        // 繪製字符
        g2d.setFont(new Font("Arial", Font.BOLD, 28));
        for (int i = 0; i < LENGTH; i++) {
            g2d.setColor(new Color(rand.nextInt(100), rand.nextInt(100), rand.nextInt(100)));
            g2d.drawString(String.valueOf(code.charAt(i)), 15 + i * 20, 30);
        }
        g2d.dispose();
        
        // 輸出
        resp.setContentType("image/jpeg");
        resp.setHeader("Pragma", "no-cache");
        resp.setHeader("Cache-Control", "no-cache");
        resp.setDateHeader("Expires", 0);
        ImageIO.write(image, "JPEG", resp.getOutputStream());
    }
}

2. 登錄處理 Servlet

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String captcha = req.getParameter("captcha");
        
        // 驗證碼校驗
        String sessionCaptcha = (String) req.getSession().getAttribute("captcha");
        if (sessionCaptcha == null || !sessionCaptcha.equals(captcha.toLowerCase())) {
            req.setAttribute("error", "驗證碼錯誤或已過期");
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
            return;
        }
        
        // 這裡對接真實業務邏輯 (DAO、Service 層)
        // 假設驗證通過
        if ("admin".equals(username) && "123456".equals(password)) {
            req.getSession().setAttribute("user", username);
            resp.sendRedirect(req.getContextPath() + "/index.jsp");
        } else {
            req.setAttribute("error", "用戶名或密碼錯誤");
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }
}

3. index.jsp - 登錄成功頁面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<% 
    String user = (String) session.getAttribute("user");
    if (user == null) { response.sendRedirect("login.jsp"); return; }
%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>歡迎頁面</title>
    <style>
        body { font-family: sans-serif; text-align: center; padding-top: 100px; background: #f5f5f5; }
        .card { background: white; display: inline-block; padding: 40px; border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,0.1); }
        .btn { display: inline-block; margin-top: 20px; padding: 10px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 6px; }
    </style>
</head>
<body>
    <div class="card">
        <h1>登錄成功!</h1>
        <p>歡迎,<strong><%= user %></strong></p>
        <a href="LogoutServlet" class="btn">退出登錄</a>
    </div>
</body>
</html>

4. 登出 Servlet

@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.getSession().invalidate();
        resp.sendRedirect(req.getContextPath() + "/login.jsp");
    }
}

部署與運行

  1. 右鍵專案 → Run As → Run on Server
  2. 選擇配置好的 Tomcat → Finish
  3. 瀏覽器自動打開 https://localhost:8080/LoginDemo/login.jsp
  4. 測試賬號:admin / 123456

常見問題排查

  • 404 錯誤:檢查 web.xml 中的 welcome-file-list、Servlet 映射路徑、專案部署路徑
  • 中文亂碼:確保 JSP 頁面、Servlet、資料庫連接均統一使用 UTF-8
  • 驗證碼不顯示:檢查 CaptchaServlet 映射路徑、JAI/ImageIO 库是否可用
  • Session 丟失:確認瀏覽器啟用 Cookie、Tomcat context.xml 未禁用 Session

進階優化方向

  • 安全強化:引入 Spring Security 或 Shiro、實現 CSRF 防護、密碼 BCrypt 加密
  • 架構分層:導入 Service/DAO 層、使用連接池 (HikariCP)、事務管理
  • 前端現代化:引入 Vue/React + Element Plus/Ant Design、RESTful API 分離
  • 容器化部署:編寫 Dockerfile、使用 Docker Compose 編排 Tomcat + MySQL + Nginx
  • 監控運維:整合 Prometheus + Grafana、ELK 日誌聚合、鏈路追蹤

通過這個完整教程,你不僅掌握了 Eclipse + Tomcat 的經典開發流程,更建立了一個可擴展的 Web 應用基礎骨架。建議在掌握基礎後,逐步引入 Spring Boot 等現代框架提升開發效率。

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