Spring中的接口驱动控制器

1、简介

在本教程中,我们将考虑Spring MVC的一个新特性,它允许我们使用通常的Java接口指定web请求。

2、概述

通常在Spring MVC中定义一个控制器时,我们用指定请求的各种注解来修饰它的方法:端点URL、HTTP请求方法、路径变量等等。
例如我们在端点/save/{id}的普通方法上添加注解:

@PostMapping("/save/{id}")
@ResponseBody
public Book save(@RequestBody Book book, @PathVariable int id) {
    // implementation
}

当我们只有一个控制器处理请求时这根本不是问题。当我们有多个具有相同方法签名的控制器时,情况会有所不同。
举例来说,我们可能有两个不同版本的控制器,由于方法迁移或类似方法而具有相同的方法签名。 在这种情况下,我们会在方法定义中添加大量重复的注解。 这显然违反了DRY(不要重复自己)原则。
如果纯Java类会出现这种情况,我们只需定义一个接口并使类实现此接口。 在控制器中方法的主要职责是由方法注解实现的,而非方法签名。
不过在Spring 5.1引入了一项新功能:

在接口上也可以检测到控制器参数注释:允许在控制器接口中完成映射约定。

我们来研究一下如何使用这个功能。

3、控制器的接口

3.1、 上下文设置

我们通过使用一个管理书籍的非常简单的REST应用程序的示例来说明新功能。 它只包含一个控制器,其方法允许我们检索和修改书籍。
在本教程中,我们只关注与该功能相关的问题。 可以在我们的GitHub仓库中找到该应用程序的所有实现问题。

3.2、接口

让我们定义一个普通的Java接口,我们不仅在其中定义方法的签名,还定义它们应该处理的Web请求的类型:

@RequestMapping("/default")
public interface BookOperations {
 
    @GetMapping("/")
    List<Book> getAll();
 
    @GetMapping("/{id}")
    Optional<Book> getById(@PathVariable int id);
 
    @PostMapping("/save/{id}")
    public void save(@RequestBody Book book, @PathVariable int id);
}

请注意,我们可能有一个类级别的注解以及方法级别的注解。 现在我们可以创建一个实现此接口的控制器:

@RestController
@RequestMapping("/book")
public class BookController implements BookOperations {
 
    @Override
    public List<Book> getAll() {...}
 
    @Override
    public Optional<Book> getById(int id) {...}
 
    @Override
    public void save(Book book, int id) {...}
 
}

我们仍然应该将类级注解@RestController或@Controller添加到控制器中。 以这种方式定义,控制器继承与Web请求的映射相关的所有注释。

为了检查控制器现在是否按预期工作,让我们运行应用程序并通过发出相应的请求来点击getAll()方法:

$ curl http://localhost:8081/book/

即使控制器实现了接口,我们也可以通过添加Web请求注解来进一步微调它。 我们可以像我们为接口做的那样:在类级别或方法级别添加注解。 事实上我们在定义控制器时使用了这种可能性:

@RequestMapping("/book")
public class BookController implements BookOperations {...}

如果我们将Web请求注解添加到控制器,它们将优先于接口的注解。 换句话说,Spring以类似于Java处理继承的方式解释控制器接口。

我们在界面中定义所有常见的Web请求属性,但在控制器中,我们可能总是对它们进行微调。

3.3、注意事项

当我们有一个接口和实现它的各种控制器时,我们可能会遇到Web请求由多个方法处理的情况。 这种情况Spring会抛出异常(模糊映射):

Caused by: java.lang.IllegalStateException: Ambiguous mapping.

如果我们用@RequestMapping装饰控制器,我们可以降低模糊映射的风险。

4、结论

在本教程中,我们考虑了Spring 5.1中引入的新功能。 现在,当Spring MVC控制器实现一个接口时,它们不仅以标准Java方式执行此操作,而且还继承了接口中定义的所有Web请求相关功能。

同样我们可以在GitHub仓库中找到相应的代码片段。

原文链接:https://www.baeldung.com/spring-interface-driven-controllers
作 者:Andrew Shcherbakov
译 者:ruyin_zh

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值