Spring Boot 中处理异常的最佳方式是什么?

问题描述 投票:0回答:3

我正在 Spring Boot 中开发一个应用程序。我想知道处理异常的最佳方法是什么。下面是我的代码,

ExceptionHandler.java
我正在使用
@ControllerAdvice
。什么是最好用的?
@ControllerAdvice
还是
@RestControllerAdvice

@ControllerAdvice
public class ExceptionHandler {

    @ExceptionHandler(NotFoundException.class)
    public ResponseEntity<ErrorResponse> notFound(NotFoundException notFoundException) {
        ErrorResponse errorResponse = new ErrorResponse(HttpStatus.NOT_FOUND, notFoundException.getMessage());
        return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.NOT_FOUND);
    }
}

并实现了服务层

@Service
如下,

@Override
public User update(User newUser) throws NotFoundException {
    Optional<User> user = userRepository.findById(newUser.getId());

    if (!user.isPresent()) throw new NotFoundException("Record Not Found!");

    return userRepository.save(newUser);
}

Controller.java
中代码如下,

@PutMapping
public User update(@RequestBody User user) {
    User updatedUser = userService.update(user);

    if (updatedUser == null) throw new SomeOtherException("Exception while Updating!");
    
    return updatedUser;
}

所以我的问题是:

上面的做法不好吗?服务层抛出异常可以吗,会被

@controlleradvice
自动捕获吗?或者只需要扔进控制器?我正在寻找处理异常的最佳实践。

java spring-boot exception controller-advice
3个回答
3
投票

你使用的方式完全没问题。

因为 @ControllerAdvice/@RestControllerAdvice 用于在整个控制器[流程]中全局处理异常。

你也可以在@Service层抛出异常。 [这是同一件事] ControllerAdvice 会抓住它。

您可以按照自己的方式自定义例外。


0
投票

我也喜欢你的方法。也许你也想看看 Lombok 和 @SneakyThrows:我发现在方法上抛出 XYZ 是不必要的,当你最后全局处理它们时。


0
投票

不要在Controller层抛出异常,而是在服务层抛出异常。实现控制器建议,以便每当服务层抛出异常时,它将执行控制器建议代码并向 API 发送响应。

需要在控制器建议中构建正确的错误消息和错误代码,它应该对用户来说是可读和可理解的。

@ControllerAdvice
public class ExceptionHandler {

    @ExceptionHandler(NotFoundException.class)
    public ResponseEntity<ErrorResponse> notFound(NotFoundException notFoundException) {
        ErrorResponse errorResponse = new ErrorResponse(HttpStatus.NOT_FOUND, notFoundException.getMessage());
        return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.NOT_FOUND);
    }
}

控制器代码,

@PutMapping
public ResponseEntity<UserDto> update(@RequestBody UserDto user) {
    UserDto userDto = userService.updatedUser(user);
    return new ResponseEntity<UserDto>(userDto, HttpStatus.OK);
}

服务层代码,

@Override
public User update(User newUser) throws NotFoundException {
    Optional<User> user = userRepository.findById(newUser.getId());

    if (!user.isPresent()) throw new NotFoundException("Record Not Found!");

    return userRepository.save(newUser);
}
© www.soinside.com 2019 - 2024. All rights reserved.