在 Spring MVC 中使用混合註解和 XML 方法進行請求對映

工程 | Rossen Stoyanchev | 2008年3月24日 | ...

在 Spring 2.5 中,可以使用註解來配置 Web 應用程式的所有部分。特別是在 Web 層,註解的應用尤其引人注目,因為開發人員傳統上依賴 SimpleFormController 和 MultiActionController 來處理表單頁面。註解的引入創造了第三種選擇,一種不需要基類即可提供與先前方法相同的靈活性。

雖然使用帶註解的 POJO 來實現 Controller 很容易理解,但在 URL 到 Controller 的對映方面,其優勢並不那麼明顯。如果使用註解來定義所有的 URL 對映規則會怎麼樣呢?事實上,這正是集中式配置在 Spring MVC 應用程式開發人員中一直以來執行良好的一個領域。

讓我們回顧一下 Spring 2.0 中 URL 到 Controller 的對映選項。

  1. Bean 名稱方法(BeanNameUrlHandlerMapping)。每個 Bean 的名稱就是它服務的路徑。儘管簡單,但如果與粗粒度的 Servlet 對映(例如 "/browse/*"、"/order/*"、"/reports/*" 等)結合使用,這種方法是可擴充套件的。
  2. 集中式方法(SimpleUrlHandlerMapping)。一個集中的地方用於檢視 URL 模式和 Controller 對映。
  3. 約定優於配置方法(ClassNameUrlHandlerMapping)。將 URL 路徑與類名匹配。因此,"/accounts/*" 被對映到一個名為 AccountsController 的 MultiActionController。無需顯式對映。

Spring 2.5 透過 @RequestMapping 註解增加了第四種選擇,該註解可以放置在類或方法上。當同時放置在類和方法上時,方法級別的對映會縮小類級別的對映範圍。

以下是一個 SimpleFormController 風格的工作流程,其中方法級別的對映由請求方法縮小範圍。


@Controller 
@RequestMapping("/editAccount")
public class EditAccountController {

    @RequestMapping(method=RequestMethod.GET)
    public Account setupForm(@RequestParam("id") Long id) {
        ...
        return account;
    }

    @RequestMapping(method=RequestMethod.POST)
    public String processSubmit(Account account) {
        ...
        return "redirect:/success.htm";
    }
}

以下是一個 MultiActionController 風格的委託,其中方法級別的對映由請求方法和相對路徑共同縮小範圍。


@Controller 
@RequestMapping("/accounts/*")
public class AccountsController {

    @RequestMapping(method=RequestMethod.GET)
    public List<Account> list() {...}

    @RequestMapping(method=RequestMethod.GET)
    public Account show(@RequestParam("id") Long id) {...}

    @RequestMapping(method=RequestMethod.POST)
    public String create(Account account) {...}
    ... 
}

正如你所見,當 "/accounts/*" 對映嵌入在程式碼中時,很難強制執行應用程式範圍內的 Controller 對映約定。至少在沒有嚴格紀律的情況下是這樣。幸運的是,有一種方法可以將外部 HandlerMapping 與方法級別的 @RequestMapping 註解結合起來。下面是一個說明這種方法如何工作的示例。


<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>
            /accounts/*=accountsController
        </value>
    <property>
</bean>

@Controller
public class AccountsController {

    @RequestMapping(method=RequestMethod.GET)
    public List<Account> list() {...}

    @RequestMapping(method=RequestMethod.GET)
    public Account show(@RequestParam("id") Long id) {...}

    @RequestMapping(method=RequestMethod.POST)
    public String create(Account account) {...}
    ... 
}

在這裡,Controller 對映駐留在中心化的基於 XML 的對映中,而 Action 方法對映透過註解指定。這種方法可以被描述為一種 POJO MultiActionController,帶有基於註解的方法分派。事實上,在最近 SpringSource 的一次溝通中,Juergen 指出提供一種基於註解的 MultiActionController 的替代方案是 Spring 2.5 的一個明確設計目標,所以我想這並不令人意外!此外,目前正在進行一項工作,允許你將方法級別的 @RequestMapping 註解與 ControllerClassNameHandlerMapping 約定結合使用(請參閱 SPR-4129)。

那麼,這一切的意義何在?

一種完全基於 XML 配置 Web 層的方法可能會變得冗長,但集中式、外部化的配置確實有其作用。擴充套件框架特定的基類,並透過深層繼承層次結構來實現控制邏輯,也可能變得冗長,我們通常認為如果可以避免,就應該避免。在 Spring MVC 2.5 中,註解可以透過將方法對映規則封裝在你的 Controller 類中來解決這兩個問題,同時還允許你將 Controller 實現為 POJO。此外,上述混合方法表明如何獲得外部化配置和基於註解的配置的最佳優勢。

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有