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

使用 Servlet 與 JSP 實作簡易 Web 聊天室系統完整教學

     編輯:Java 綜合教學

前言

本文將詳細介紹如何運用 Java EE 技術(Servlet、JSP、Filter、Listener、Cookie 等)建構一個功能完整的 Web 聊天室系統。系統包含使用者登入驗證、記住密碼、聊天訊息即時顯示、線上人數統計等核心功能,並採用 frameset 框架佈局模擬類 QQ 群聊介面。

系統需求分析

核心功能需求

  1. 登入頁面:提供使用者名稱、密碼輸入欄位,包含送出與重置按鈕
  2. 登入驗證邏輯:透過 Servlet 處理登入請求,驗證使用者名稱與學號密碼,成功導向聊天介面,失敗導向錯誤頁
  3. 聊天介面:使用 frameset 分割視窗,上方顯示歡迎資訊與線上人數,左側好友列表,右側聊天區包含訊息顯示區與輸入發送區
  4. 記住密碼功能:利用 Cookie 儲存使用者帳密,下次免輸入自動登入

進階功能(選做)

  1. 線上人數統計:實作 HttpSessionListener 監聽 Session 建立與銷毀,即時統計在線人數
  2. 字元編碼過濾器:實作 Filter 統一設定請求/回應 UTF-8 編碼,解決中文亂碼問題

系統架構設計

系統採用 MVC 模式,核心元件如下:

  • Login.jsp:登入頁面,讀取 Cookie 自動填入帳密
  • Main.java (Servlet):處理登入邏輯、驗證帳密、管理 Cookie、轉發請求
  • Welcome.jsp:登入成功主頁,使用巢狀 frameset 切割三個框架
  • Header.jsp:頂部框架,顯示歡迎訊息與線上人數
  • Left.jsp:左側框架,好友分群清單(使用 jQuery 實現摺疊效果)
  • Main.jsp:主聊天區,包含訊息顯示 textarea 與輸入發送表單
  • InputInformation.java (Servlet):處理訊息發送,將聊天記錄附加時間戳後轉發回顯示頁
  • CodeFilter.java:字元編碼過濾器,攔截所有請求設定 UTF-8
  • OnlineListener.java:Session 監聽器,維護 application 範圍在線人數計數器

核心程式碼實作解析

1. 登入頁面與 Cookie 自動填入

Login.jsp 在頁面載入時讀取請求中的 Cookie,若存在 username 與 password 則自動填入表單:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
    String username = "", password = "";
    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
        for (Cookie cookie : cookies) {
            if ("username".equals(cookie.getName())) {
                username = java.net.URLDecoder.decode(cookie.getValue(), "UTF-8");
            } else if ("password".equals(cookie.getName())) {
                password = java.net.URLDecoder.decode(cookie.getValue(), "UTF-8");
            }
        }
    }
%>
<form action="Main" method="post">
    使用者名稱: <input type="text" name="username" value="<%=username%>"><br>
    密碼: <input type="password" name="password" value="<%=password%>"><br>
    <input type="checkbox" name="save_password" value="save"> 記住密碼
    <input type="submit" value="登入" name="login">
    <input type="reset" value="重置">
</form>

2. 登入驗證 Servlet (Main.java)

核心邏輯:驗證帳密對照表、管理 Cookie 存活期、請求轉發與重導向:

@WebServlet("/Main")
public class Main extends HttpServlet {
    private static final String[] VALID_USERS = {"柳真","劉仁傑","吳超","張浩東","陳初相"};
    private static final String[] VALID_PWDS = {"201421092073","201421092068","201421092077","201421092082","201421092119"};

    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String userName = request.getParameter("username");
        String passWord = request.getParameter("password");
        String savePwd = request.getParameter("save_password");

        // 驗證帳密
        boolean valid = false;
        for (int i = 0; i < VALID_USERS.length; i++) {
            if (VALID_USERS[i].equals(userName) && VALID_PWDS[i].equals(passWord)) {
                valid = true; break;
            }
        }

        if (valid) {
            // 存入 Session
            request.getSession().setAttribute("nameSession", userName);
            
            // 處理記住密碼 Cookie
            if ("save".equals(savePwd)) {
                Cookie uCookie = new Cookie("username", URLEncoder.encode(userName, "UTF-8"));
                Cookie pCookie = new Cookie("password", URLEncoder.encode(passWord, "UTF-8"));
                uCookie.setMaxAge(60*60*24*3); // 3 天
                pCookie.setMaxAge(60*60*24*3);
                response.addCookie(uCookie);
                response.addCookie(pCookie);
            }
            request.getRequestDispatcher("welcome.jsp").forward(request, response);
        } else {
            response.sendRedirect("loginFail.jsp");
        }
    }
}

3. 聊天主介面

Welcome.jsp (Frameset 佈局)

<frameset rows="100,*" cols="*" frameborder="no" border="0" framespacing="0">
    <frame src="header.jsp" name="topFrame" scrolling="auto" noresize="noresize" />
    <frameset cols="213,*" frameborder="no" border="0" framespacing="0">
        <frame src="left.jsp" name="leftFrame" scrolling="no" noresize="noresize" />
        <frame src="main.jsp" name="mainFrame" scrolling="auto" />
    </frameset>
</frameset>

Header.jsp (顯示線上人數)

<td align="center">
    歡迎 <%=session.getAttribute("nameSession")%> 訪問! 
    當前在線人數為 <%=application.getAttribute("peopleOnline")%> 人
</td>

Main.jsp (聊天輸入與顯示區)

<form action="InputInformation" method="post" target="mainFrame">
    <textarea name="show_textarea" cols="105" rows="25" readonly>
        <%=request.getAttribute("input_textarea") != null ? request.getAttribute("input_textarea") : ""%>
    </textarea><br>
    <textarea name="input_textarea" cols="105" rows="5"></textarea><br>
    <input type="submit" value="發送">
</form>

4. 訊息處理 Servlet (InputInformation.java)

注意:此處使用實例變數儲存聊天記錄僅供示範,實際生產環境應使用資料庫或共享快取:

@WebServlet("/InputInformation")
public class InputInformation extends HttpServlet {
    private String chatRecord = ""; // 簡易記憶體儲存

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String msg = request.getParameter("input_textarea");
        String user = (String) request.getSession().getAttribute("nameSession");
        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        
        chatRecord += user + " " + msg + " " + time + "\n";
        request.setAttribute("input_textarea", chatRecord);
        request.getRequestDispatcher("main.jsp").forward(request, response);
    }
}

5. 字元編碼過濾器

@WebFilter(filterName = "CodeFilter", urlPatterns = {"/*"})
public class CodeFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        chain.doFilter(request, response);
    }
}

6. 線上人數監聽器

@WebListener
public class OnlineListener implements HttpSessionListener {
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        Integer count = (Integer) ctx.getAttribute("peopleOnline");
        ctx.setAttribute("peopleOnline", (count == null) ? 1 : count + 1);
    }
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        Integer count = (Integer) ctx.getAttribute("peopleOnline");
        if (count != null && count > 0) ctx.setAttribute("peopleOnline", count - 1);
    }
}

部署設定

web.xml 關鍵設定

<web-app version="3.0" ...>
    <listener>
        <listener-class>com.liuzhen.chart.OnlineListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>Main</servlet-name>
        <servlet-class>com.liuzhen.chart.Main</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>InputInformation</servlet-name>
        <servlet-class>com.liuzhen.chart.InputInformation</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Main</servlet-name>
        <url-pattern>/Main</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>InputInformation</servlet-name>
        <url-pattern>/InputInformation</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
</web-app>

執行結果與測試

系統成功運行於 GlassFish Server,測試場景:

  • IE 瀏覽器登入 → 顯示在線 1 人
  • Chrome 瀏覽器登入 → 顯示在線 2 人
  • 360 瀏覽器登入 → 顯示在線 3 人
  • 驗證 Cookie 記住密碼功能:關閉瀏覽器重開自動填入帳密
  • Filter 確保中文訊息正確顯示無亂碼

專案原始碼

完整程式碼已上傳至 Coding.net:專案連結

總結

本專案完整展示了 Java Web 核心技術的整合應用:Servlet 處理業務邏輯、JSP 負責視圖渲染、Filter 解決編碼問題、Listener 實現應用層級狀態統計、Cookie 實現客戶端狀態持久化。雖然使用 frameset 與記憶體儲存聊天記錄屬於教學示範架構,但核心設計模式為後續學習 WebSocket、Spring Boot 等現代框架奠定了堅實基礎。

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