【问题标题】:ControllerAdvice, ExceptionHandler and try catch block in RestControllerRestController 中的 ControllerAdvice、ExceptionHandler 和 try catch 块
【发布时间】:2020-12-17 20:46:24
【问题描述】:

我有关于@ControllerAdvice@ExceptionHandler 的一般性问题。我有一个注释为 @RestController 的休息控制器,它有 2 个 API。如果参数验证失败,则抛出 MethodArgumentNotValidException。我创建了ExceptionHandler 来处理这个问题:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public ResponseEntity<String> handleException(MethodArgumentNotValidException e) throws Exception {
        return new ResponseEntity<>(e.getBindingResult().getGlobalError().getDefaultMessage(), HttpStatus.BAD_REQUEST);
    }
}

如果我想在发生此异常时记录某些内容,我可以在return 语句之前添加一行代码,例如:

LOG.info("something happened");

它会记录它然后将 BAD_REQUEST 返回给调用者吗?

【问题讨论】:

    标签: java spring rest exception annotations


    【解决方案1】:

    如果我想在这个异常发生时记录一些东西,我可以在 return 语句之前添加一行代码吗:

    LOG.info("发生了什么事");

    它会记录它,然后将 BAD_REQUEST 返回给调用者吗?

    是的。这就是使用@ExceptionHandlers 的目的。它们有助于减少处理项目中定义的多个休息端点的异常的代码。这也可以作为记录异常的单点,从而避免这种反模式:

    //BAD
    class SomeService {
        public SomeEntity someMethod() {
            try {
                /* stuff... */
            } catch (Exception e) {
                //No need to log the exception here
                log.error("An exception happened", e);
                throw e;
            }
        }
    }
    

    不过,您仍然可以获得一些好处,例如包装异常并重新抛出它们:

    //GOOD
    class SomeService {
        public SomeEntity someMethod(String param) {
            try {
                /* stuff... */
            } catch (Exception e) {
                //You may use this to perform other logic like setting specific message or wrap your exception
                log.error("Unexpected behaviour with param {}", param);
                throw new MyCustomException("Some message", e);
            }
        }
    }
    

    您可以将@ExceptionHandler 视为一个巨大的catch 块,用于所有其余端点和特定类型的异常。

    此外,您的 GlobalExceptionHandler 类成为具有相关逻辑的组件,用于处理后端抛出的每个异常并处理如何向客户端报告。

    【讨论】:

    • 好答案! :) 一个例外(不是双关语),当您需要在GlobalExceptionHandler 中记录一些您无权访问的上下文时,在发生异常的方法中记录某些内容很有用。
    • @KajHejer 很好(也没有双关语)。让我重新表述那部分,因为我的意图是不记录异常堆栈跟踪两次。
    • 我明白了。所以如果我需要一些特定的上下文,最好登录方法,如果它是通用的,最好使用@ExceptionHandler。好答案。谢谢!
    猜你喜欢
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    • 2017-07-03
    • 2015-09-05
    相关资源
    最近更新 更多