Spring Web MVC中的嵌套控制器

时间:2015-12-14 23:34:12

标签: java spring spring-mvc

我正在编写一个Web API服务器,它提供三种相关类型的资源:作者,组和渠道。每个频道必须由一个作者或组拥有,访问控制由请求用户与相关作者或组的关系决定,因此我计划创建一个URL结构,如:

  1. GET / authors / {authorId} - 查看特定作者
  2. POST / authors / {authorId} / channels - 创建属于该作者的频道
  3. GET / authors / {authorId} / channels - 列出属于该作者的频道
  4. GET / authors / {authorId} / channels / {channelId} - 查看属于该作者的特定频道
  5. GET / groups / {groupId} - 查看特定群组
  6. POST / groups / {groupId} / channels - 创建属于该组的频道
  7. GET / groups / {groupId} / channels - 列出属于该组的频道
  8. GET / groups / {groupId} / channels / {channelId} - 查看属于该群组的特定频道
  9. 完成的服务器将有更多的路径来处理作者,组和渠道;这些是作为例子给出的。

    尝试使用Spring Web MVC中的三个控制器(即AuthorsController,GroupsController,ChannelsController)进行此操作是否合理?如何使用RequestMapping注释将它们连接在一起?有没有办法分解这些在Spring Web MVC中更有意义的职责,但仍然保留了凝聚力?

    N.B。我见过a similar question asked,但问题和答案都集中在内部类。

1 个答案:

答案 0 :(得分:3)

你应该根据“单一责任原则”组织课程:课程应该做“一件事”,无论是什么。

在这种情况下,似乎有一个类AuthorController来处理作者或组的HTTP机制通常会没问题。这种控制器的映射看起来像这样(Groovy为了简单起见并使用DomainClassConverter):

@RequestMapping('/authors')
@RestController
class AuthorController {

    @RequestMapping('/{id}')
    Author singleResource(@PathVariable Author id) {
        id
    }
}

现在您的要求似乎在多个类中具有相同的行为,这听起来像是可能用于继承,但您还有一个对象Channel可以是由多种所有者拥有,这听起来像是可能用于仿制药。

如果作者和群组之间的频道管理逻辑相同,那么我建议使用abstract class ChannelController<O extends ChannelOwner>来处理所有/channel映射;如果它不同,那么使ChannelController<O>成为一个接口,然后只声明映射。

请注意,如果您使用Spring Security处理授权@RequestMapping annotations are inherited when you override/implement an abstract method, but @PreAuthorize and similar are not,则必须将安全注释复制到最低级别的实现类。您应始终使用MockMvc来确保您收到禁止访问的相应禁止响应。