服务和控制器层异常处理设计模式
Service and controller layer exception handling design pattern
所以这是我当前实现的 rest-api 端点,我想处理一些极端情况,例如找不到用户或公寓,所以我会抛出并适合例外,但如何显示我在控制器中处理它?现在它还没有真正起作用,如果我设置一个不存在的 id 它会像往常一样工作,而且我没有收到相应的错误消息。
服务层:
public void delete(Long flatId) {
flatRepository.findById(flatId).ifPresentOrElse(flat -> {
List<User> residents = flat.getResidents();
residents.forEach(resident -> resident.setFlat(null));
flatRepository.delete(flat);
},
() -> new ResourceNotFoundException("Flat " + flatId + " found"));
}
控制器层:
@DeleteMapping("/flats/{flatId}")
public void deleteFlat(@PathVariable Long flatId) {
flatService.delete(flatId);
}
全局异常处理程序:
@ControllerAdvice
@RestController
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public final ErrorDetails handleResourceNotFoundException(ResourceNotFoundException ex) {
return new ErrorDetails(LocalDateTime.now(), ex.getMessage(), 404);
}
@ExceptionHandler(ResourceAlreadyDefinedException.class)
@ResponseStatus(HttpStatus.CONFLICT)
public final ErrorDetails handleResourceAlreadyDefinedException(ResourceAlreadyDefinedException ex) {
return new ErrorDetails(LocalDateTime.now(), ex.getMessage(), 409);
}
}
更新:我创建了这个全局异常处理程序,但是如果我向我的 api 发送一个带有不存在 ID 的删除请求,它不会向我发送 404,它只会回复 200。而如果在这种情况下,我有一个 return 值,它按预期工作。
public Flat get(Long id) {
return flatRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Flat " + id + " not found"));
}
@GetMapping("/flats/{flatId}")
public ResponseEntity<Flat> getFlat(@PathVariable Long flatId) {
return ResponseEntity.ok(flatService.get(flatId));
}
您可以将 @ControllerAdvice
与 @ExceptionHandler
结合使用,为所有控制器和特定类型的异常实施全局异常处理。
查看 here 示例。
所以这是我当前实现的 rest-api 端点,我想处理一些极端情况,例如找不到用户或公寓,所以我会抛出并适合例外,但如何显示我在控制器中处理它?现在它还没有真正起作用,如果我设置一个不存在的 id 它会像往常一样工作,而且我没有收到相应的错误消息。
服务层:
public void delete(Long flatId) {
flatRepository.findById(flatId).ifPresentOrElse(flat -> {
List<User> residents = flat.getResidents();
residents.forEach(resident -> resident.setFlat(null));
flatRepository.delete(flat);
},
() -> new ResourceNotFoundException("Flat " + flatId + " found"));
}
控制器层:
@DeleteMapping("/flats/{flatId}")
public void deleteFlat(@PathVariable Long flatId) {
flatService.delete(flatId);
}
全局异常处理程序:
@ControllerAdvice
@RestController
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public final ErrorDetails handleResourceNotFoundException(ResourceNotFoundException ex) {
return new ErrorDetails(LocalDateTime.now(), ex.getMessage(), 404);
}
@ExceptionHandler(ResourceAlreadyDefinedException.class)
@ResponseStatus(HttpStatus.CONFLICT)
public final ErrorDetails handleResourceAlreadyDefinedException(ResourceAlreadyDefinedException ex) {
return new ErrorDetails(LocalDateTime.now(), ex.getMessage(), 409);
}
}
更新:我创建了这个全局异常处理程序,但是如果我向我的 api 发送一个带有不存在 ID 的删除请求,它不会向我发送 404,它只会回复 200。而如果在这种情况下,我有一个 return 值,它按预期工作。
public Flat get(Long id) {
return flatRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Flat " + id + " not found"));
}
@GetMapping("/flats/{flatId}")
public ResponseEntity<Flat> getFlat(@PathVariable Long flatId) {
return ResponseEntity.ok(flatService.get(flatId));
}
您可以将 @ControllerAdvice
与 @ExceptionHandler
结合使用,为所有控制器和特定类型的异常实施全局异常处理。
查看 here 示例。