我认为这些是无法恢复的业务约束破坏。
我目前的解决方案是异常层次结构。
public abstract class UncheckedApplicationException extends RuntimeException {
//omitted factory methods and constructors
public abstract String getStatusCode();
public abstract String getI18nCode();//ignore this if you don't need i18n
public abstract String[] getI18nArgs();//ignore this if you don't need i18n
}
任何自定义异常都会扩展此异常。我认为这可以避免这样的代码:
try {
//invoke your application service
} catch (InsufficientInventoryException e) {
statusCode = INSUFFICIENT_INVENTORY;
} catch (ExpriedPriceException e) {
statusCode = EXPIRED_PRICE;
} catch (NoSuchProductException e) {
statusCode = NO_SUCH_PRODUCT;
} catch (Exception e) {
statusCode = UNKNOWN;
}
控制器代码片段:
try {
//invoke your application service here
statusCode = SUCCESS;
message = messageSource.getSuccess(locale));
} catch (UncheckedApplicationException e) {
statusCode = e.getStatusCode();
message = messageSource.getMessage(e, locale));
} catch (Exception e) {
statusCode = UNKNOWN;
message = messageSource.getUnknownError(e, locale));
}
//add statusCode & message to modelAttribute
如果您的控制器组织良好(但非常困难),您可以使用 @ExceptionHandler 来减少样板的 try-catch 代码。
使用异常的另一个原因是应用程序服务通常用于划定事务边界。如果要回滚,必须抛出异常。