2

我有一个使用(本地)会话 bean 公开服务的 JEE5 应用程序。

当服务执行期间发生内部故障时,JBoss(5.0.1) 会抛出 RuntimeException 并将其封装在 javax.ejb.EJBTransactionRolledbackException 中。

问题是接收此 EJBTransactionRolledbackException 的客户端应用程序可以访问有关导致运行时异常的详细信息,从而暴露我的应用程序的内部架构。我不希望那样。

相反,我希望 JBoss 始终将暴露的会话 bean 抛出的 RuntimeException 封装到单个(简单的) TechnicalException 中(没有原因)。

实现这一目标的最佳方法是什么?(使用拦截器?使用 JBoss 配置?)

4

2 回答 2

4

最后,根据之前的回答和我个人的研究,我保留了以下解决方案。

我创建了一个专门用于管理服务器故障的拦截器:

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 { ...

这是故障屏障模式的实现。

任何运行时异常都会被捕获、记录并使用 TechnicalException 向客户端发出错误信号(没有内部细节)。已检查的异常将被忽略。

RuntimeException 处理是集中的,并与任何业务方法分开。

于 2009-06-30T12:44:27.803 回答
1

任何 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"));

希望这就是你要找的。

干杯

于 2009-06-25T03:59:01.150 回答