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

Spring MVC 核心原理與電話簿應用實戰(上)

     編輯:Java 相關知識

系列背景

本文為「Apache Geronimo 與 Spring 框架」系列第 5 部分,聚焦 Spring MVC 核心模組,透過擴充電話簿應用示範控制器、表單綁定、驗證等關鍵機制。

為什麼需要 MVC?

傳統 Web 開發中,視圖(JSP)直接嵌入業務邏輯與資料存取,導致:

  • 視圖與模型緊耦合,修改其一必牽動另一
  • 多視圖共用同一模型時,邏輯重複散落
  • 單元測試困難,無法隔離業務邏輯

MVC 引入 Controller 作為中介層:

  1. 接收請求
  2. 協調模型更新
  3. 選擇視圖渲染結果

Spring MVC 核心架構

DispatcherServlet 為核心前端控制器,職責:

  • 根據 HandlerMapping 將請求路由至對應 Controller
  • Controller 返回 ModelAndView
  • 委派 ViewResolver 解析視圖名稱並渲染
  • 支援國際化、主題、檔案上傳等擴展

關鍵介面與實作

介面核心實作說明
ControllerSimpleFormController, MultiActionController處理請求、綁定表單、驗證、決定視圖
Validator自訂實作表單資料驗證,錯誤收集至 Errors 物件
ViewResolverInternalResourceViewResolver, ResourceBundleViewResolver視圖名稱 → 具體 View 實例

電話簿應用擴充實作

1. 主頁控制器 PhonebookHomeController

public class PhonebookHomeController extends SimpleFormController {
    private IPhonebookDataProvider pbDataProvider;

    protected Object formBackingObject(HttpServletRequest request) {
        // GET 請求時提供表單後端物件:此處直接回傳列表供顯示
        return pbDataProvider.getPhonebookEntries();
    }

    protected ModelAndView onSubmit(Object command) {
        return new ModelAndView(new RedirectView(getSuccessView()));
    }
    // setter 注入 pbDataProvider
}

2. Spring 配置控制器 Bean

<bean id="phonebookHomeController" class="phonebook.controller.PhonebookHomeController">
  <property name="sessionForm" value="true"/>
  <property name="bindOnNewForm" value="true"/>
  <property name="formView" value="home-mvc"/>
  <property name="successView" value="addentry-mvc"/>
  <property name="commandName" value="phonebookEntries"/>
  <property name="commandClass" value="java.util.List"/>
  <property name="pbDataProvider" ref="phonebook"/> <!-- AOP 代理 -->
</bean>

3. JSP 視圖 home-mvc.jsp(JSTL + Spring Tags)

<c:forEach items="${phonebookEntries}" var="pbEntry">
  <tr>
    <td><input type="radio" name="data_i" onclick="setId(${pbEntry.entryID},${pbEntry.rowID})"/></td>
    <td><c:out value="${pbEntry.firstName}"/> <c:out value="${pbEntry.lastName}"/></td>
    ...
  </tr>
</c:forEach>

4. 新增條目控制器與驗證

public class AddEntryFormController extends SimpleFormController {
    protected Object formBackingObject(HttpServletRequest request) {
        return new PhonebookEntry(); // 空表單物件
    }

    protected ModelAndView onSubmit(Object command) {
        PhonebookEntry entry = (PhonebookEntry) command;
        pbDataProvider.addEntry(entry);
        return new ModelAndView(new RedirectView(getSuccessView() + ".act"));
    }
}

// 驗證器
public class PhonebookEntryValidator implements Validator {
    public boolean supports(Class clazz) {
        return PhonebookEntry.class.equals(clazz);
    }
    public void validate(Object obj, Errors errors) {
        PhonebookEntry e = (PhonebookEntry) obj;
        if (e.getFirstName() == null || e.getFirstName().isEmpty())
            errors.rejectValue("firstName", "error.firstName.empty", "First name cannot be empty");
        if (e.getLastName() == null || e.getLastName().isEmpty())
            errors.rejectValue("lastName", "error.lastName.empty", "Last name cannot be empty");
    }
}

5. 表單綁定 addentry-mvc.jsp

<spring:nestedPath path="phonebookEntry">
  <spring:bind path="firstName">
    <input type="text" name="${status.expression}" value="${status.value}"/>
    <c:if test="${status.error}"><span class="error"><c:out value="${status.errorMessage}"/></span></c:if>
  </spring:bind>
  ...
</spring:nestedPath>

6. URL 映射 web.xml

<servlet>
  <servlet-name>phonebook</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>phonebook</servlet-name>
  <url-pattern>*.act</url-pattern>
</servlet-mapping>

Spring MVC 優勢回顧

  • 角色劃分清晰:Controller/Validator/Command/Form/ViewResolver 各司其職
  • 可重用業務物件:現有 POJO 直接作為 Command/Form 物件,無需繼承框架基類
  • 靈活綁定與驗證:支援巢狀屬性、集合、自訂 PropertyEditor
  • 視圖解析策略豐富:可插拔自訂 ViewResolver
  • 標籤庫簡化 JSP:spring:bind、spring:nestedPath 消除手工表單處理樣板碼

下一步預告

第 6 部分將展示如何在同一應用中整合 JSP、Tiles、Velocity、PDF 多種視圖技術,並示範視圖技術的熱切換能力。

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