本文記錄一個輕量級新聞發布系統的完整構建過程:管理員登錄驗證、新聞發布靜態化存儲、MD5 生成唯一文件名、前台動態列表展示。技術棧:JSP + JavaBean + PostgreSQL 8.0 + Tomcat 5.5,展示早期 JSP 開發典型模式與靜態化優化思路。
index.jsp (登錄) → check.jsp (驗證) → main.jsp (發布頁) → pub.jsp (處理發布) → display.jsp (前台列表)
DB (連接)、CheckBean (登錄驗證)、PubBean (發布邏輯)、MD5 (標題哈希)CREATE TABLE administrator ( admin CHAR(16), password CHAR(32) -- 存 MD5 密文 ); CREATE TABLE news ( title CHAR(255), page CHAR(255) -- 靜態文件名,如 newsice + MD5(title) + .htm );
public class DB {
private Connection conn; private Statement stmt; private ResultSet rs;
public DB() {
Class.forName("org.postgresql.Driver");
conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/news?user=admin&password=");
stmt = conn.createStatement();
}
public void update(String sql) { stmt.executeUpdate(sql); }
public ResultSet query(String sql) { return stmt.executeQuery(sql); }
}
public class CheckBean {
private String admin, password, message; private DB db = new DB();
public String checkIt() {
ResultSet rs = db.query("SELECT * FROM administrator WHERE admin='" + admin + "'");
if (rs.next()) {
String dbPwd = rs.getString("password").trim();
message = dbPwd.equals(password) ? "密碼正確!" : "密碼錯誤!";
} else { message = "用戶不存在!"; }
return message;
}
// setter/getter...
}
public class PubBean {
private String title, context; private DB db = new DB(); private MD5 md5 = new MD5();
public void pubIt() {
title = new String(title.getBytes("8859_1"), "GB2312"); // 編碼轉換
context = new String(context.getBytes("8859_1"), "GB2312");
String titleMD5 = md5.getMD5ofStr(title); // 32 位十六進制
db.update("INSERT INTO news VALUES('" + title + "','" + titleMD5 + "')");
String file = "newsice" + titleMD5 + ".htm";
PrintWriter pw = new PrintWriter(new FileOutputStream(file));
pw.println("" + title + " ");
pw.println(context);
pw.close();
}
}
採用 RFC 1321 標準算法,核心流程:填充 → 分組 → 四輪非線性函數變換 (F/G/H/I) → 輸出 128 位摘要。提供 getMD5ofStr(String) 返回 32 位十六進制字符串,保證標題唯一性映射到唯一文件名。
<jsp:useBean id="checkBean" class="login.CheckBean"/>
<jsp:setProperty name="checkBean" property="admin" value="<%=request.getParameter("admin").trim()%>"/>
<jsp:setProperty name="checkBean" property="password" value="<%=request.getParameter("password").trim()%>"/>
<%
String result = checkBean.checkIt();
if ("密碼正確!".equals(result)) {
session.setAttribute("admin", request.getParameter("admin"));
response.sendRedirect("main.jsp");
} else {
<jsp:forward page="index.jsp">
<jsp:param name="error" value="<%=result%>"/>
</jsp:forward>
}
%>
<%
String admin = (String)session.getAttribute("admin");
if (admin == null) { response.sendRedirect("index.jsp"); return; }
%>
<jsp:useBean id="pubBean" class="login.PubBean"/>
<jsp:setProperty name="pubBean" property="title" value="<%=request.getParameter("title").trim()%>"/>
<jsp:setProperty name="pubBean" property="context" value="<%=request.getParameter("context")%>"/>
<%
pubBean.pubIt();
response.sendRedirect("display.jsp");
%>
<%
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection("jdbc:odbc:PostgreSQL", "", "");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM news");
while (rs.next()) {
%>
<a href="news/ice<%=rs.getString(2)%>.htm" target="_blank"><%=rs.getString(1)%></a><br>
<%
}
%>
| 技術點 | 實現方式 | 優勢 |
|---|---|---|
| 靜態化發布 | 新聞內容寫 .htm 文件,DB 存文件名 | 前台讀取無需查庫,極大降低 DB 壓力,頁面極快 |
| 文件名唯一性 | MD5(title) 32 位十六進制 | 標題唯一 → 文件名唯一,無衝突,無需 UUID/序列 |
| 登錄狀態維持 | Session 存 admin 名,各頁攔截檢查 | 簡單有效,符合早期 JSP 開發模式 |
| 編碼處理 | new String(bytes, "GB2312") 手動轉碼 | 解決早期容器預設 ISO-8859-1 導致的中文亂碼 |
| 頁面跳轉 | sendRedirect (重定向) + jsp:forward (轉發) | 登錄成功重定向防重複提交,失敗轉發保留錯誤信息 |
此系統雖屬教學/早期生產級別,但完整展示了「靜態化發布降低 DB 壓力」、「MD5 保證文件名唯一」、「JavaBean 封裝業務邏輯」、「JSP 標籤簡化代碼」等經典模式。理解這些模式的來龍去脈,有助於在現代技術棧中做出更合理的架構決策。