RestController 中的 ControllerAdvice、ExceptionHandler 和 try catch 块
ControllerAdvice, ExceptionHandler and try catch block in RestController
我有关于 @ControllerAdvice
和 @ExceptionHandler
的一般性问题。我有一个带有 2 个 API 的注释 @RestController
的休息控制器。如果参数验证失败,它会抛出 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");
它会记录它然后 return BAD_REQUEST 返回给调用者吗?
If I want to log something when this exception happens, can I just add line of code before return statement like:
LOG.info("something happened");
Will it log it and then return BAD_REQUEST back to the caller?
是的。这就是使用 @ExceptionHandler
的目的。它们有助于减少用于处理项目中定义的多个剩余端点的异常的代码。这也可以作为记录异常的单点,从而避免这种反模式:
//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
class 成为具有关联逻辑的组件,用于处理后端抛出的每个异常并处理如何向客户端报告异常。
我有关于 @ControllerAdvice
和 @ExceptionHandler
的一般性问题。我有一个带有 2 个 API 的注释 @RestController
的休息控制器。如果参数验证失败,它会抛出 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");
它会记录它然后 return BAD_REQUEST 返回给调用者吗?
If I want to log something when this exception happens, can I just add line of code before return statement like:
LOG.info("something happened");
Will it log it and then return BAD_REQUEST back to the caller?
是的。这就是使用 @ExceptionHandler
的目的。它们有助于减少用于处理项目中定义的多个剩余端点的异常的代码。这也可以作为记录异常的单点,从而避免这种反模式:
//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
class 成为具有关联逻辑的组件,用于处理后端抛出的每个异常并处理如何向客户端报告异常。