Har*_*nna 5 spring exception spring-boot
我还在学春天.我有一个应用程序设置,我正在尝试理解Spring中的异常处理.
我正在@ControllerAdvice用来处理异常.在我的应用程序有几层如Services,Controllers,Models和Repositories.我应该在哪个层处理异常?或者我应该在适当的时候处理每一层中的异常?
这是在Spring中启动异常处理的好方法:
步骤1 -创建特定的DefaultExceptionHandler类,并使用@ControllerAdvice批注对其进行批注.在此处理程序类中,您有不同的方法,捕获预期和意外的异常,这些异常使用@ExceptionHandler批注进行批注:
@ControllerAdvice("com.stackoverflow.example")
@SuppressWarnings("WeakerAccess")
public class DefaultExceptionHandler extends ResponseEntityExceptionHandler {
private final Logger log = LoggerFactory.getLogger("DefaultExceptionHandler");
private final MessageSourceAccessor messageSource;
@Autowired
public DefaultExceptionHandler(MessageSourceAccessor messageSource) {
Assert.notNull(messageSource, "messageSource must not be null");
this.messageSource = messageSource;
}
@ExceptionHandler(ApplicationSpecificException.class)
public ResponseEntity<Object> handleApplicationSpecificException(ApplicationSpecificExceptionex) {
final Error error = buildError(ex);
return handleExceptionInternal(ex, ex.getHttpStatus(), error);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleException(Exception ex) {
final Error error = buildError(ex);
return handleExceptionInternal(ex, HttpStatus.INTERNAL_SERVER_ERROR, error);
}
}
Run Code Online (Sandbox Code Playgroud)
第2步 -创建一个特定于应用程序的异常(ApplicationSpecificException类),用于预期的异常,并在任何级别抛出此异常,它将被Spring接收:
public class ApplicationSpecificException extends RuntimeException {
private static final long serialVersionUID = 1L;
private final ExceptionType exceptionType;
public ApplicationSpecificException(ExceptionType exceptionType, Object... messageArguments) {
super(MessageFormat.format(exceptionType.getMessage(), messageArguments));
this.exceptionType = exceptionType;
}
public ApplicationSpecificException(ExceptionType exceptionType, final Throwable cause, Object... messageArguments) {
super(MessageFormat.format(exceptionType.getMessage(), messageArguments), cause);
this.exceptionType = exceptionType;
}
public HttpStatus getHttpStatus() {
return exceptionType.getStatus();
}
public ExceptionType getExceptionType() {
return exceptionType;
}
}
Run Code Online (Sandbox Code Playgroud)
ExceptionType是一个枚举:
public enum ExceptionType {
HTTP_INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "An internal server error occurred.");
//you can specify your own exception types...
private HttpStatus status;
private String message;
ExceptionType(HttpStatus status, String message) {
this.status = status;
this.message = message;
}
public HttpStatus getStatus() {
return status;
}
public String getMessage() {
return message;
}
}
Run Code Online (Sandbox Code Playgroud)
第3步 -最后,创建了一个ExceptionFactory类.这允许您在应用程序日志中自动记录异常:
public class ExceptionFactory {
private static final Logger LOG = LoggerFactory.getLogger(ExceptionFactory.class);
public static ApplicationSpecificException create(final Throwable cause, final ExceptionType exceptionType, final Object... messageArguments) {
LOG.error(MessageFormat.format(exceptionType.getMessage(), messageArguments), cause);
return new ApplicationSpecificException (exceptionType, cause, messageArguments);
}
public static ApplicationSpecificException create(final ExceptionType exceptionType, final Object... messageArguments) {
LOG.error(MessageFormat.format(exceptionType.getMessage(), messageArguments));
return new TerminologyServerException(exceptionType, messageArguments);
}
}
Run Code Online (Sandbox Code Playgroud)
步骤4 -在应用程序的任何位置,您现在可以抛出异常,这将在应用程序日志中记录异常.由于Spring @ControllerAdvice注释,DefaultExceptionHandler抛出并拾取此异常:
throw ExceptionFactory.create(ExceptionType.INTERNAL_SERVER_ERROR);
Run Code Online (Sandbox Code Playgroud)
像这样,您可以将异常处理流程作为一个跨领域的问题来应对.不会将内部服务器错误传播给最终用户,并且DefaultExceptionHandler会处理预期和意外异常.异常被分配了一个HTTP错误代码和错误消息,它将返回给客户端.
| 归档时间: |
|
| 查看次数: |
4908 次 |
| 最近记录: |