Java spring boot中的子控制器
让我们想象一个场景,我有一个Spring Boot应用程序(在控制器/服务/存储库模式中),其中包含汽车控制器。现在,我想创建如下路径:Java spring boot中的子控制器,java,spring,rest,spring-boot,architecture,Java,Spring,Rest,Spring Boot,Architecture,让我们想象一个场景,我有一个Spring Boot应用程序(在控制器/服务/存储库模式中),其中包含汽车控制器。现在,我想创建如下路径: "/api/cars/bmw" "/api/cars/mercedes" "/api/cars/audi" 等等。对于这些汽车生产商中的每一家,我希望有多个端点,其中一些端点对于所有汽车生产商来说都是通用的(不确定这是否真的重要,但仅仅是为了它,比如说“/order”和“/cancelOrder”),但其中一些端点不同 现在,实现这个场景的正确方法是什么?是
"/api/cars/bmw"
"/api/cars/mercedes"
"/api/cars/audi"
等等。对于这些汽车生产商中的每一家,我希望有多个端点,其中一些端点对于所有汽车生产商来说都是通用的(不确定这是否真的重要,但仅仅是为了它,比如说“/order”和“/cancelOrder”),但其中一些端点不同
现在,实现这个场景的正确方法是什么?是否有一种方法可以为/car/{producer}
路径创建一个CarController,它可以作为其他控制器(如AudiController)处理/car/audi
请求的代理?在一个控制器中有3个汽车生产商,每个汽车生产商有一个服务是可以的,但是如果我只有一个汽车控制器,有30个将产生很多注入依赖项(30个服务注入控制器)
我相信node.js Express框架将允许我们在汽车“控制器”脚本中实现这一点(不确定它们在Express中是否被称为控制器或什么):
春天也有类似的可能性吗?或者这可能是个坏主意,一个反模式
另一个非常简单但似乎不那么优雅的想法是跳过CarController并实现:
- 带有
@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
注释):
子控制器类:
@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/cancelOrder
或http://localhost:8080/api/cars/Audi/cancelOrder
。此外,我们可以通过以下方式调用公共端点:http://localhost:8080/api/cars/common
感谢您的回复,尽管这似乎并不能解决依赖关系过多的问题。我仍然需要做一个类似于case switch语句的语句,该语句接受生产者字符串,并根据其“奥迪”、“宝马”或“梅赛德斯”的位置,它将调用audiService、bmwService或mercedeservice,这意味着我仍然需要将所有汽车的服务作为控制器中的依赖项。问题的重点是消除控制器中的大量依赖关系。我想我一开始没有抓住你的重点,我对我的答案做了一些编辑,希望能有所帮助。如果你需要根据输入解决不同的服务,那么我想你需要在某处实现一个工厂
模式。理想情况下,Controller
可以将调用解析为更通用的CarService
接口,该接口可以依赖CarFactory
解析适当的运行时实例,从而解析功能。
@RequestMapping("/api/cars/")
public class BaseCarController {
@GetMapping("/common")
public String common() {
return "Common stuff";
}
}
@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.";
}
}