在 Spring MVC 中使用混合注解和 XML 方法进行请求映射

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

在 Spring 2.5 中,可以使用注解来配置 Web 应用程序的所有部分。在 Web 层看到应用的注解尤其令人关注,因为开发人员传统上依赖 SimpleFormController 和 MultiActionController 来处理表单页面。注解的引入提供了一个第三种选择,它不需要基类,同时仍然提供以前方法的灵活性。

虽然使用带注解的 POJO 来实现控制器很容易看出其优雅之处,但在 URL 到控制器的映射方面,好处并不那么明显。使用注解定义所有 URL 映射规则会是什么样子呢?实际上,在这个领域,集中式配置对 Spring MVC 应用程序的开发人员非常有效。

让我们回顾一下 Spring 2.0 中 URL 到控制器的映射选项

  1. bean 名称方法 (BeanNameUrlHandlerMapping)。每个 bean 的名称都包含它服务的路径。尽管它很简单,但如果与粗粒度的 servlet 映射相结合(例如,“/browse/*”、“/order/*”、“/reports/*”等),这种方法可以扩展。
  2. 集中式方法 (SimpleUrlHandlerMapping)。一个查看 URL 模式和控制器映射的中心位置。
  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/*”映射嵌入在代码中,因此很难强制执行控制器映射的应用程序范围约定。至少没有一些严格的规则不行。幸运的是,有一种方法可以将外部 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) {...}
    ... 
}

这里的控制器映射位于基于 XML 的中心映射中,而动作方法映射则通过注解指定。这种方法可以描述为具有基于注解的方法调度的 POJO MultiActionController。事实上,在 SpringSource 内部最近的一次沟通中,Juergen 指出,提供基于注解的 MultiActionController 替代方案是 Spring 2.5 的明确设计目标,所以我想这并不令人意外!此外,正在进行的工作允许您将方法级别的 @RequestMapping 注解与 ControllerClassNameHandlerMapping 约定结合起来(参见 SPR-4129)。

所有这一切的意义是什么?

完全基于 XML 的 Web 层配置方法可能会变得很冗长,但是集中式、外部化的配置确实有其作用。扩展具有深层继承层次结构的框架特定基类来实现控制逻辑也可能会变得冗长,我们通常认为如果可以避免的话应该避免这种情况。在 Spring MVC 2.5 中,注解可以帮助解决这两个问题,方法是将方法映射规则封装在控制器类中,并允许您将控制器实现为 POJO。此外,上述混合方法显示了如何获得外部化配置和基于注解的配置的最佳效果。

获取 Spring 时事通讯

通过 Spring 时事通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring在一个简单的订阅中提供对 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部