让我们想象一下一个场景,其中我有一个Spring Boot应用程序(采用控制器/服务/存储库模式),其中包含用于汽车的控制器。现在,我想创建看起来像这样的路径:
"/api/cars/bmw"
"/api/cars/mercedes"
"/api/cars/audi"
以此类推。对于每个汽车制造商,我都希望有多个端点,其中一些端点对于所有汽车制造商都是通用的(不确定是否真的很重要,但是仅出于此目的,我们可以说“ / order”和“ / cancelOrder” ),但其中一些有所不同。
现在实现该方案的正确方法是什么?有没有一种方法可以为/car/{producer}
路径创建CarController,该路径将成为AudiController处理/car/audi
请求的其他控制器的代理?在一个控制器中有3个汽车生产商,并为每个汽车生产商提供服务是可以的,但是如果我只有一个CarController,那么拥有30个汽车生产商将产生很多注入的依赖项(将30个服务注入到控制器中)。
我相信node.js Express框架将允许我们在汽车的“控制器”脚本中执行此操作(不确定它们是否在express中称为控制器或什么):
var app = express();
app.use('/audi', '{path to audi controller script}');
春季有类似的可能性吗?还是这可能是个坏主意,反模式?
另一个很简单但似乎不太优雅的想法是跳过CarController并实现一个:
带有@RequestMapping("/api/cars/audi")
带有@RequestMapping("/api/cars/bmw")
带有@RequestMapping("/api/cars/mercedes")
等
那么,什么是最好的主意?
答案 0 :(得分:1)
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
注释):
@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.";
}
}
我们可以这样称呼产生特定端点:
http://localhost:8080/api/cars/Mercedes/cancelOrder
或http://localhost:8080/api/cars/Audi/cancelOrder
。此外,我们可以通过以下方式调用公共端点:http://localhost:8080/api/cars/common