java - Spring Boot 中的子 Controller

标签 java spring rest spring-boot architecture

让我们想象一个场景,我有一个 Spring Boot 应用程序(采用 Controller /服务/存储库模式),其中包含汽车 Controller 。现在我想创建如下所示的路径:

"/api/cars/bmw"
"/api/cars/mercedes"
"/api/cars/audi"

等等。对于每个汽车生产商,我希望有多个端点,其中一些端点对于所有汽车生产商来说都是通用的(不确定这是否真的重要,但只是为了它,例如“/order”和“/cancelOrder”) ),但其中一些不同。

现在实现这个场景的正确方法是什么?有没有办法为 /car/{ Producer} 路径创建一个 CarController ,它将作为其他 Controller 的代理,例如处理 /car/audi 请求的 AudiController ?在一个 Controller 中拥有 3 个汽车生产商,并为每个汽车生产商提供一个服务是可以的,但如果我只有一个 CarController,那么拥有 30 个汽车生产商会产生大量注入(inject)依赖项(将 30 个服务注入(inject)到 Controller 中)。

我相信node.js Express框架将允许我们在汽车“ Controller ”脚本中执行此操作(不确定它们是否被称为express中的 Controller 或什么):

var app = express();
app.use('/audi', '{path to audi controller script}');

Spring中有类似的可能性吗?或者这可能是一个坏主意,一个反模式?

另一个非常简单但似乎不太优雅的想法是跳过 CarController 并实现:

  • AudiController 与 @RequestMapping("/api/cars/audi")

  • BmwController 与 @RequestMapping("/api/cars/bmw")

  • MercedesController 与 @RequestMapping("/api/cars/mercedes")

等等

那么,最好的主意是什么?

最佳答案

Spring为此提供了@PathVariable,可以通过以下方式使用它:

@RestController
@RequestMapping("/api/cars/")
public class MyController {

    @GetMapping
    @RequestMapping("{producer}/cancelOrder")
    public String cancelOrder(@PathVariable String producer) {
        return "Cancel order for " + producer;
    }
}

我们可以这样调用这个端点:http://localhost:8080/api/cars/Mercedes/cancelOrder

Spring 中没有子 Controller 这样的东西。如果您想为每个具有某些通用功能的生产者创建一个单独的 Controller ,您可以使用继承:

父 Controller 类(请注意,它没有任何 Controller 注释):

@RequestMapping("/api/cars/")
public class BaseCarController {
    @GetMapping("/common")
    public String common() {
        return "Common stuff";
    }
}

子 Controller 类:

@RestController
public class MercedesController extends BaseCarController{

    private MercedesService mercedesService;

    // Spring will autowire this by default, no need to add @Autowired
    public MercedesController(MercedesService mercedesService) {
        this.mercedesService = mercedesService;
    }

    @GetMapping
    @RequestMapping("Mercedes/cancelOrder")
    public String cancelOrder() {
        return "Cancel order for Mercedes.";
    }
}

@RestController
public class AudiController extends BaseCarController{
    private AudiService audiService;

    // Spring will autowire this by default, no need to add @Autowired
    public AudiController(AudiService audiService) {
        this.audiService = audiService;
    }

    @GetMapping
    @RequestMapping("Audi/cancelOrder")
    public String cancelOrder() {
        return "Cancel order for Audi.";
    }
}

我们可以像这样调用生成特定的端点: http://localhost:8080/api/cars/Mercedes/cancelOrderhttp://localhost:8080/api/cars/Audi/cancelOrder。此外,我们可以通过以下方式调用公共(public)端点:http://localhost:8080/api/cars/common

关于java - Spring Boot 中的子 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54724107/

相关文章:

java - 当到达某个点时滚动对象

java - 构建时 Maven MOJO 执行失败

java - 注册用户后自动登录

java - 从 Spring MVC 中的自定义 Controller 访问服务层

java - 错误无法加载资源: the server responded with a status of 403 () en angular

google-app-engine - 谷歌翻译获取同义词和例子

java - Oracle Coherence 通读配置

Java 8 嵌套列表作为父级中的单例列表

java - Spring 相当于波浪号 (~) 用于从 ASP.NET 进行路由?

RESTful 设计 : return an empty object as a template for create new form