基於 **Servlet 3.0 + JSP + DOM4J XML 存儲** 的輕量級用戶註冊/查詢/刪除系統,無需數據庫,適合教學、原型驗證、嵌入式場景。採用 MVC 分層:
User 實體 + UserDao 接口/實現 (DOM4J 操作 users.xml) + IDGenerate/DomFactory 工具類index.jsp(註冊表單/用戶列表)RegServlet (註冊/列表)、DelServlet (刪除)package cn.hncu.user.domain;
public class User {
private String id; // UUID 無連字符
private String name;
private String pwd;
// 構造函數、getter/setter、equals/hashCode (按 id)、toString 省略
}
public interface UserDao {
boolean reg(User user); // 註冊,名稱唯一
List<User> queryAllUsers(); // 查詢所有
void delUser(String id); // 刪除
}
public class UserDaoImpl implements UserDao {
private Document dom = DomFactory.getDom(); // 單例 DOM 文檔
@Override
public boolean reg(User user) {
// XPath 檢查用戶名是否存在(區分大小寫)
Node exist = dom.selectSingleNode("//user[name='" + user.getName() + "']");
if (exist != null) return false;
Element root = dom.getRootElement();
Element eUser = root.addElement("user");
String id = IDGenerate.getID();
eUser.addAttribute("id", id);
eUser.addElement("name").setText(user.getName());
eUser.addElement("pwd").setText(user.getPwd()); // 明文存儲,生產必須加密!
DomFactory.save();
return true;
}
@Override
public List<User> queryAllUsers() {
List<User> list = new ArrayList<>();
for (Element e : dom.selectNodes("//user")) {
User u = new User();
u.setId(e.attributeValue("id"));
u.setName(e.elementText("name"));
list.add(u);
}
return list;
}
@Override
public void delUser(String id) {
Node node = dom.selectSingleNode("//user[@id='" + id + "']");
if (node != null) {
node.getParent().remove(node);
DomFactory.save();
}
}
}
// DomFactory: 單例加載/保存 users.xml (classpath 下)
public class DomFactory {
private static Document dom;
private static String filePath;
static {
try {
SAXReader reader = new SAXReader();
filePath = DomFactory.class.getClassLoader().getResource("users.xml").getPath();
dom = reader.read(filePath);
} catch (Exception e) { throw new ExceptionInInitializerError(e); }
}
public static Document getDom() { return dom; }
public static boolean save() {
try (FileOutputStream fos = new FileOutputStream(filePath);
XMLWriter writer = new XMLWriter(fos)) {
writer.write(dom); return true;
} catch (Exception e) { return false; }
}
}
// IDGenerate: UUID 去連字符
public class IDGenerate {
public static String getID() { return UUID.randomUUID().toString().replace("-", ""); }
}
@WebServlet("/reg")
public class RegServlet extends HttpServlet {
private UserDao dao = new UserDaoImpl();
@Override // GET: 顯示用戶列表
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<User> users = dao.queryAllUsers();
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("<table border='1'><tr><th>操作</th><th>姓名</th></tr>");
for (User u : users) {
out.println("<tr><td><a href='/usersWeb/del?id=" + u.getId() + "'>刪除</a></td>" +
"<td>" + u.getName() + "</td></tr>");
}
out.println("</table>");
}
@Override // POST: 註冊
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String name = req.getParameter("name");
String pwd = req.getParameter("pwd");
boolean ok = dao.reg(new User(name, pwd));
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println(ok ? "恭喜 " + name + " 註冊成功!" : "用戶名已存在,註冊失敗!");
out.println("<a href='javascript:history.back()'>返回</a>");
}
}
@WebServlet("/del")
public class DelServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
dao.delUser(req.getParameter("id"));
resp.sendRedirect(req.getContextPath() + "/index.jsp"); // 重定向防重複提交
}
}
<%@ page contentType="text/html;charset=UTF-8" %>
<html><body>
<h2>用戶註冊</h2>
<form action="reg" method="post">
姓名: <input name="name" required/><br/>
密碼: <input type="password" name="pwd" required/><br/>
<input type="submit" value="註冊"/>
</form>
<hr/>
<a href="reg">查看所有用戶</a>
</body></html>
<web-app version="3.0" ...>
<welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<users></users>
| 點 | 現狀 | 生產級改進 |
|---|---|---|
| 密碼存儲 | 明文 | **BCrypt/Argon2 哈希 + 隨機鹽**,絕不存明文 |
| 併發安全 | DOM 非線程安全 | 用 ReentrantReadWriteLock 保護 DAO 方法,或遷移到數據庫 |
| XML 性能 | 全量加載內存 | 數據量 > 1萬 建議遷移 MySQL/PostgreSQL + 連接池 |
| XPath 注入 | 字符串拼接 | 用參數化 XPath 或預編譯,防惡意輸入如 ' or '1'='1 |
| 事務一致性 | 無 | 數據庫事務 / 補償機制 |
| 前端交互 | 頁面跳轉 | AJAX + JSON + 統一異常處理 |
<dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>2.1.3</version> </dependency>
<dependency> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> <version>1.4.01</version> </dependency>
本文提供了基於 Servlet/JSP/DOM4J/XML 的完整用戶註冊管理系統源碼,涵蓋分層架構、XML 持久化、註冊/列表/刪除全流程。代碼結構清晰,適合理解 Java Web 基礎、XML 操作、MVC 分層。但**生產環境必須替換為數據庫、加密存儲、併發控制、參數化查詢**,並引入 Spring Boot / MyBatis 等成熟框架提升開發效率與系統健壯性。