代码约定说控制器中没有逻辑。所有这些都应在服务层中处理。我的问题尤其是关于返回ResponseEntity。
应该在RestController还是在Service层中处理?
我尝试了两种方式。我认为RestController是返回ResponseEntity的合适位置。因为我们在RestController中使用映射。
另一方面,我们知道控制器不应包含任何逻辑。
@GetMapping("/{id}")
public ResponseEntity<Employee> getEmployee(@PathVariable Long id) {
return ResponseEntity.ok(employeeService.findEmployeeById(id);
}
或
@GetMapping("/{id}")
public ResponseEntity<Employee> getEmployee(@PathVariable Long id) {
return employeeService.findEmployeeById(id);
}
用于异常处理的ControllerAdvice是我的另一个问题。最好使用哪种方法?
感谢您的进步。
答案 0 :(得分:8)
代码约定说控制器中没有逻辑。
不是。代码约定表示每一层必须执行自己负责的逻辑。
计算结果,检索请求所请求/需要的数据显然不是其余的控制器工作,而是发送http响应,返回ResponseEntity
的工作就是它的工作。所以这看起来是正确的方法:
@GetMapping("/{id}")
public ResponseEntity<Employee> getEmployee(@PathVariable Long id) {
return ResponseEntity.ok(employeeService.findEmployeeById(id);
}
如果ResponseEntity
由您的服务产生,则您的服务将与Http层耦合。这是不可取的,并且使其不太可重用为服务。
答案 1 :(得分:3)
状态码,响应正文,标头是REST的核心部分之一
控制器应关注接受请求,请求正确的域服务来处理请求以及将响应传递到正确的位置。
正确的是,控制器不应在此处执行 all 业务逻辑,而是发送HTTP响应应该在Controller中完成,而不是在服务中完成。
尽管可以使用@ResponseStatus(HttpStatus.XXX)
发送状态代码,这在必须根据条件发送状态代码的情况下可能无济于事。您可以创建通常具有正文,消息和状态代码的自定义ResponseDTO。
public ResponseEntity<ResponseDTO> method() {
return new ResponseEntity<ResponseDTO>(response,response.getStatus());
}
答案 2 :(得分:1)
首先。业务逻辑应在服务层中进行处理,在服务层中,您可以使用存储库对数据访问进行抽象。这有助于进行模块化编程,使可重用的代码段彼此分离。这是模型,视图,控制器(MVC)和基础设计背后的思想。在测试方面,使应用程序的这些部分能够各自完成工作并相互独立进行测试会变得更加容易。当我们要处理对特定方法(而不是控制器赋予我们的功能的URL)的安全访问时,在服务方法中抽象逻辑也将有所帮助。因此,您的RestController应该调用您的服务层并返回适当的响应。
第二。对于(Rest)ControllerAdvice,拥有异常处理程序有助于返回自定义错误。这是异常处理程序类内部的以下示例。
@ExceptionHandler(CustomerExistException.class)
public final ResponseEntity<ApiErrorResponse> handleCustomerExistException(
CustomerExistException ex) {
ApiErrorResponse errorResponse = new ApiErrorResponse("USR_04", "The email already exists."
+ "Email", String.valueOf(HttpStatus.BAD_REQUEST));
return new ResponseEntity<ApiErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
}`