Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.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 restful API验证_Java_Spring_Spring Boot_Validation - Fatal编程技术网

Java 分层体系结构中的Spring boot restful API验证

Java 分层体系结构中的Spring boot restful API验证,java,spring,spring-boot,validation,Java,Spring,Spring Boot,Validation,今天,我与我们的一位团队成员就如何验证Controller和Service层中的RESTful API输入进行了一次大讨论,我觉得今天不适合进行更大的争论。因此,我们有一个具有分层架构的spring boot微服务应用程序 Controller --> Service --> Repository 参数是在每一层进行验证,或者只是在控制器层进行验证,例如,我们有控制器和POST请求,并对输入请求体使用验证 控制器: @PostMapping(value = "/", consume

今天,我与我们的一位团队成员就如何验证
Controller
Service
层中的RESTful API输入进行了一次大讨论,我觉得今天不适合进行更大的争论。因此,我们有一个具有分层架构的spring boot微服务应用程序

Controller --> Service --> Repository
参数是在每一层进行验证,或者只是在
控制器
进行验证,例如,我们有
控制器
POST
请求,并对输入请求体使用验证

控制器:

@PostMapping(value = "/", consumes = {"application/json"}, produces = {"application/json"})
public ResponseEntity<Detail> createConfig(

        @NotNull(message = "{error.message.config_detail}")
        @RequestBody @Validated Config config) {

    return new ResponseEntity<>(configService.create(config.getConfigId(), config.getTaskId()), HttpStatus.CREATED);
  }
public Detail create(@Valid @NotNull Long configId, @NotNull Integer taskId) {

   // some business logic to convert to entity and saving to database

    return repository.save(entity));
}
如果验证成功,则从
Config
调用带有某些属性的
Service
方法

服务:

@PostMapping(value = "/", consumes = {"application/json"}, produces = {"application/json"})
public ResponseEntity<Detail> createConfig(

        @NotNull(message = "{error.message.config_detail}")
        @RequestBody @Validated Config config) {

    return new ResponseEntity<>(configService.create(config.getConfigId(), config.getTaskId()), HttpStatus.CREATED);
  }
public Detail create(@Valid @NotNull Long configId, @NotNull Integer taskId) {

   // some business logic to convert to entity and saving to database

    return repository.save(entity));
}
因此,如果我们看到上面的代码,同样的验证在
控制器
服务
上进行,因此我认为没有必要在
服务
层进行验证,在控制器层执行验证,如果输入错误,则将
400
500
扔给用户但团队中的另一个人也建议在每个块中对块中使用的任何东西进行验证,以便单个代码段是安全的(关注单元而不是集成路径)。

我知道在这种情况下我可能是错的,但仍然无法理解每一层的验证(我同意空检查),因此建议在每一层进行验证

Controller --> validation call service

Service ---> validation and call business 

Business ---> validation and call repository

Repository --> save

但首选的验证方式是什么?根据我的判断,如果
控制器
输入有效,则调用
服务
,执行业务逻辑并调用
存储库
。如果我错了,请纠正我,这样我就可以按照建议的模式进行验证。你是对的:如果可能,验证应该放在控制器中。在我看来,验证数据超过1次是没有意义的。
另请参见干燥原理,它是情境性的。需要在服务层执行一些验证。比方说,您将需要更改对象的状态,但前提是满足某些条件等。 其中一部分,作为经验法则,我遵循以下准则:
如果您的服务通过RMI公开给其他服务,则服务层验证是强制性的,如果不进行控制器级验证。

除非您在其他项目中将服务和/或存储库用作库,否则多次进行验证是没有意义的。 如果控制器是访问附加层的唯一类,则无需进行额外的验证,因为只有您和您的控制器访问SpringBean。您和控制器控制着使用有效参数访问服务

进行多次验证的缺点是编写更复杂的服务,包括单元测试。 它比较慢。 更改验证将花费更长的时间,因为必须更改多个层,包括单元测试。 几层上的验证在时间上可能会有所不同


首选的方法是在控制器中(甚至之前)进行一次验证,并编写集成测试以确保其功能。

如果数据无效,为什么需要调用服务并在那里进行验证?