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

JavaEE 三層架構實戰:用戶模塊 (DOM4J 模擬數據庫 + 工廠模式解耦)

     編輯:Java 綜合教學

JavaEE 三層架構實戰:用戶模塊 (DOM4J 模擬數據庫 + 工廠模式解耦)

本文通過一個完整的**用戶註冊/登入/註銷**案例,展示經典 JavaEE 三層架構落地:Servlet (控制層) → Service (業務層) → DAO (數據層) → Domain (實體),並採用 **DOM4J 操作 XML 模擬數據庫**、**工廠模式解耦創建**、**XPath 查詢**、**BeanUtils 自動封裝**等實用技術。

一、專案包結構規範

com.tsh
├─ web        // Servlet 控制器
├─ service    // 業務邏輯接口及實現
├─ dao        // 數據訪問接口及實現
├─ domain     // 實體類
├─ util       // 工具類
├─ factory    // 工廠類 (解耦創建)
├─ exception  // 自定義異常
└─ test       // 單元測試

二、依賴庫

  • dom4j:XML 解析與寫入
  • jstl:JSP 標簽庫
  • commons-beanutils:表單數據自動封裝到 Bean
  • junit:單元測試

三、核心代碼實現

3.1 領域模型

package com.tsh.domain;

import java.io.Serializable;

public class User implements Serializable {
    private String username;
    private String password;
    private String password_confirm; // 前端確認密碼用

    // Getter/Setter 省略
}

3.2 數據層:XmlUserDao (DOM4J + XPath)

package com.tsh.dao;

import com.tsh.domain.User;
import com.tsh.util.XmlDaoUtil;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import java.util.List;

public class XmlUserDao {
    // 根據用戶名查找
    public User findUserByUsername(String username) {
        Document dom = XmlDaoUtil.getDom();
        Element root = dom.getRootElement();

        // XPath 查詢://user[@username='xxx']
        List list = root.selectNodes("//user[@username='" + username + "']");
        if (list.size() > 0) {
            Element userElement = list.get(0);
            User user = new User();
            user.setUsername(userElement.attributeValue("username"));
            user.setPassword(userElement.attributeValue("password"));
            user.setPassword_confirm(userElement.attributeValue("password")); // 簡化
            return user;
        }
        return null;
    }

    // 添加用戶
    public void addUser(User user) {
        Document dom = XmlDaoUtil.getDom();
        Element root = dom.getRootElement();

        Element userElement = DocumentHelper.createElement("user");
        userElement.setAttributeValue("username", user.getUsername());
        userElement.setAttributeValue("password", user.getPassword());

        root.add(userElement);
        XmlDaoUtil.writeXml(dom); // 回寫文件
    }
}

3.3 工具類:XmlDaoUtil (單例模式緩存 Document)

package com.tsh.util;

import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import java.net.URL;

public class XmlDaoUtil {
    private static URL path = XmlDaoUtil.class.getClassLoader().getResource("user.xml");
    private static Document dom;

    static {
        SAXReader reader = new SAXReader();
        try {
            dom = reader.read(path);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Document getDom() {
        return dom;
    }

    public static void writeXml(Document dom) {
        // 實現寫回文件邏輯 (省略)
    }
}

3.4 數據文件

user.xml (放置於 src 根目錄,編譯到 classes)

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user username="admin" password="admin"/>
</users>

config.properties

dao=com.tsh.dao.XmlUserDao
service=com.tsh.service.impl.UserServiceImpl

3.5 業務層與工廠解耦

// Service 接口
public interface UserService {
    void register(User user) throws UserExistException;
    User login(String username, String password) throws UserNotFoundException, PasswordErrorException;
}

// Service 實現
public class UserServiceImpl implements UserService {
    private UserDao userDao = (UserDao) BeanFactory.getBean("dao");

    public void register(User user) throws UserExistException {
        if (userDao.findUserByUsername(user.getUsername()) != null) {
            throw new UserExistException("用戶名已存在");
        }
        userDao.addUser(user);
    }
    // login 實現省略
}

// 簡易工廠 (反射 + 配置文件)
public class BeanFactory {
    private static Properties props = new Properties();
    static {
        try {
            props.load(BeanFactory.class.getClassLoader().getResourceAsStream("config.properties"));
        } catch (IOException e) { e.printStackTrace(); }
    }

    public static Object getBean(String key) {
        String className = props.getProperty(key);
        try {
            return Class.forName(className).newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

3.6 Web 層 Servlet

@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        // 1. BeanUtils 自動封裝表單數據到 User
        User user = new User();
        try {
            BeanUtils.populate(user, req.getParameterMap());
        } catch (Exception e) { throw new RuntimeException(e); }

        // 2. 調用 Service
        UserService service = (UserService) BeanFactory.getBean("service");
        try {
            service.register(user);
            resp.sendRedirect("login.jsp?msg=註冊成功");
        } catch (UserExistException e) {
            req.setAttribute("msg", e.getMessage());
            req.getRequestDispatcher("register.jsp").forward(req, resp);
        }
    }
}

四、關鍵技術點總結

  1. DOM4J + XPath: selectNodes("//user[@username='...']") 極其適合 XML 模擬數據庫查詢,無需學習 SQL。
  2. 靜態緩存 Document: XmlDaoUtil 靜態塊加載一次,讀取極快;寫入時需同步考慮併發 (簡單項目可加鎖)。
  3. 工廠模式 + 反射 + 配置文件: 實現 **DAO/Service 實現類零硬編碼**,擴展新實現只改 properties。
  4. BeanUtils.populate: 一行代碼完成 request.getParameterMap() → Bean 屬性 映射,自動類型轉換。
  5. 分層異常傳遞: DAO 拋運行時異常 → Service 轉業務異常 → Servlet 捕獲轉發錯誤頁,職責清晰。

五、擴展方向

  • 將 XML 替換為 MySQL + MyBatis/JPA,DAO 接口**不變**,僅換實現類與配置。
  • 引入 Spring IOC 容器替換簡易 BeanFactory,獲得 AOP 事務、依賴注入完整能力。
  • 前端升級為 Vue/React + REST API,Servlet 轉為 Spring MVC @RestController。

這個微型專案雖簡單,卻包含了**分層架構、接口解耦、配置驅動、ORM 思想、異常體系**等企業級開發核心基因,是進階 JavaEE 的優秀起步樣板。

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