Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java spring boot中的子控制器_Java_Spring_Rest_Spring Boot_Architecture - Fatal编程技术网

Java 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”),但其中一些端点不同 现在,实现这个场景的正确方法是什么?是

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

"/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.";
    }
}