Как скрыть детали RuntimeException от EJB-клиента?
У меня есть приложение JEE5, которое предоставляет сервисы с использованием (локальных) сессионных компонентов.
Когда во время выполнения службы возникает внутренняя ошибка, RuntimeException генерируется и инкапсулируется JBoss(5.0.1) в исключение javax.ejb.EJBTransactionRolledbackException.
Проблема заключается в том, что клиентские приложения, получающие это исключение EJBTransactionRolledbackException, могут получить доступ к подробной информации об исключительной ситуации времени выполнения, обнажив внутреннюю архитектуру моего приложения. И я не хочу этого.
Вместо этого я хотел бы, чтобы JBoss всегда инкапсулировал исключение RuntimeException, генерируемое открытыми сессионными компонентами, в одно (и простое) TechnicalException (без причины).
Какой лучший способ достичь этого? (Использование перехватчиков? Использование конфигурации JBoss?)
2 ответа
Наконец, основываясь на предыдущем ответе и моих личных исследованиях, я сохранил следующее решение.
Я создал перехватчик, предназначенный для управления ошибками сервера:
public class FaultBarrierInterceptor {
@AroundInvoke
public Object intercept(final InvocationContext invocationContext) throws Exception {
try {
return invocationContext.proceed();
} catch (final RuntimeException e) {
final Logger logger = Logger.getLogger(invocationContext.getMethod().getDeclaringClass());
logger.error("A fault occured during service invocation:" +
"\n-METHOD: " + invocationContext.getMethod() +
"\n-PARAMS: " + Arrays.toString(invocationContext.getParameters()), e);
throw new TechnicalException();
}
}}
Выданное техническое исключение расширяет EJBException и не раскрывает причину RuntimeException:
public class TechnicalException extends EJBException {}
Я использую этот перехватчик во всех государственных службах:
@Stateless
@Interceptors({FaultBarrierInterceptor.class})
public class ShoppingCardServicesBean implements ShoppingCardServices { ...
Это реализация шаблона Fault Barrier.
Любое исключение во время выполнения перехватывается, регистрируется, и клиенту сообщается об ошибке (без внутренних подробностей) с помощью TechnicalException. Проверенные исключения игнорируются.
Обработка RuntimeException централизована и отделена от любых бизнес-методов.
Любое RuntimeException расширяет java.lang.Exception.
Спецификация EJB обеспечивает обработку для 2 типов исключений (приложение и система)
Если вы хотите создать системное исключение, вы обычно делаете это так:
try {
.... your code ...
}catch(YourApplicationException ae) {
throw ae;
}catch(Exception e) {
throw new EJBException(e); //here's where you need to change.
}
Чтобы скрыть внутренние детали системного исключения, просто замените:
throw new EJBException(e);
с:
throw new EJBException(new TechnicalException("Technical Fault"));
Надеюсь, это то, что вы искали.
ура