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

基於包結構的 Java Web 請求路由實作範例

     編輯:Java 程式設計入門

設計概念

傳統 Servlet 開發需在 web.xml 逐一對應 URL 與類別。本範例展示一種基於「套件命名慣例」的自動路由機制:透過 Filter 攔截請求,依 URL 路徑動態推導處理類別與方法,實現零配置的請求分派。

核心架構

  • WebFilter:實作 javax.servlet.Filter,攔截所有請求並執行路由邏輯
  • BaseAction:抽象基底類別,提供 ServletRequest/ServletResponse 的注入與存取
  • 命名慣例:基礎套件 + URL路徑轉換 + "Action" 後綴 定位處理類別

關鍵程式碼解析

1. 路由過濾器 WebFilter

public class WebFilter implements Filter {
    public static final String BASE_PACKAGE = "com.hongyuan";
    public static final String CLASS_FLAG = "Action";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        if (!hasResouce(request)) {  // 靜態資源直接放行
            String requestPath = ((HttpServletRequest) request).getServletPath();
            // 移除副檔名與尾端斜線
            if (requestPath.indexOf(".") >= 0) {
                requestPath = requestPath.substring(0, requestPath.indexOf("."));
            }
            if (requestPath.endsWith("/")) {
                requestPath = requestPath.substring(0, requestPath.length() - 1);
            }

            // 組裝完整類別名稱:com.hongyuan.模組.功能Action
            String className = BASE_PACKAGE + requestPath.replaceAll("/", ".") + CLASS_FLAG;
            String methodName = request.getParameter("method");
            if (methodName == null || "".equals(methodName.trim())) {
                methodName = "index";  // 預設方法
            }

            try {
                Class clazz = Class.forName(className);
                Object instance = initContext(clazz, request, response);
                Method method = clazz.getMethod(methodName, new Class[]{});
                Object result = method.invoke(instance, new Object[]{});
                response.getWriter().print(result);
            } catch (Exception e) {
                e.printStackTrace(response.getWriter());
            }
        } else {
            chain.doFilter(request, response);  // 靜態資源交由預設 Servlet 處理
        }
    }

    private boolean hasResouce(ServletRequest request) {
        String realPath = request.getServletContext().getRealPath(
                ((HttpServletRequest) request).getServletPath());
        return new File(realPath).exists();
    }

    private Object initContext(Class clazz, ServletRequest request, ServletResponse response)
            throws Exception {
        Object instance = clazz.newInstance();
        clazz.getMethod("setRequest", ServletRequest.class).invoke(instance, request);
        clazz.getMethod("setResponse", ServletResponse.class).invoke(instance, response);
        return instance;
    }
    // init/destroy 略
}

2. 基底 Action 類別

public abstract class BaseAction {
    protected ServletRequest request;
    protected ServletResponse response;

    public ServletRequest getRequest() { return request; }
    public void setRequest(ServletRequest request) { this.request = request; }
    public ServletResponse getResponse() { return response; }
    public void setResponse(ServletResponse response) { this.response = response; }
}

使用範例

假設專案結構如下:

com.hongyuan
├── user
│   └── UserAction.java      // 對應 /user/user.do
└── order
    └── OrderAction.java     // 對應 /order/order.do

UserAction 實作:

package com.hongyuan.user;

public class UserAction extends BaseAction {
    public String index() {
        return "用戶首頁";
    }

    public String login() {
        String username = request.getParameter("username");
        return "歡迎 " + username;
    }
}

請求 /user/user.do?method=login&username=Tom 將自動路由至 UserAction.login()。

優缺點分析

優點缺點
零 XML 配置,依慣例自動路由類別命名需嚴格遵循規範
新增功能只需建立對應 Action 類別反射調用效能略低於直接調用
集中式例外處理與前置/後置邏輯靜態資源判斷邏輯較簡單

擴充建議

  • 加入權限攔截、日誌記錄、參數驗證等橫切關注點
  • 支援 RESTful 風格 URL(如 /user/123 映射至 getById(123))
  • 整合依賴注入容器(Spring/Guice)管理 Action 實例生命週期
  • 快取 Class 與 Method 物件提升效能

總結

此路由模式適用中小型專案,能大幅減少設定檔維護成本。核心在於「慣例優於配置」,配合反射機制實現動態分派,是理解框架底層運作的良好切入點。

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