在 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 模式和控制器映射。
  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) {...}
    ... 
}

这里的控制器映射驻留在基于 XML 的中心映射中,而操作方法映射通过注解指定。 这种方法可以描述为具有基于注解的方法分发的 POJO MultiActionController。 事实上,在 SpringSource 最近的一次沟通中,Juergen 指出,提供基于注解的 MultiActionController 替代方案是 Spring 2.5 的一个明确设计目标,因此我想这并不令人惊讶! 此外,目前正在进行的工作允许您将方法级别的 @RequestMapping 注解与 ControllerClassNameHandlerMapping 约定结合使用(请参阅 SPR-4129)。

那么这一切的意义是什么?

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

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

遥遥领先

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

了解更多

获得支持

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

了解更多

即将举行的活动

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

查看全部