如何从EJB客户端隐藏RuntimeException详细信息?

时间:2021-06-24 20:14:25

I have a JEE5 application that exposes services using (local) session beans.

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

When an internal fault occurs during service execution, a RuntimeException is thrown and encapsulated by JBoss(5.0.1) in a javax.ejb.EJBTransactionRolledbackException.

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

The problem is that client applications receiving this EJBTransactionRolledbackException can access detailled informations about the cause runtime exception, exposing internal architecture of my application. And I don't want that.

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

Instead, I would like JBoss to always encapsulate RuntimeException thrown by exposed session beans into a single (and simple) TechnicalException (with no cause).

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

What's the best way to achieve this ? (Using interceptors ? Using JBoss configuration ?)

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

2 个解决方案

#1


Finally, based on previous answer and my personal researches, I retained the folowing solution.

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

I've created an interceptor dedicated to manage server faults :

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

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();
    }
}}

The thrown technical exception extends EJBException and does not expose the cause RuntimeException:

抛出的技术异常扩展了EJBException,并且没有暴露原因RuntimeException:

public class TechnicalException extends EJBException {}

I use this interceptor in all public services :

我在所有公共服务中使用这个拦截器:

@Stateless
@Interceptors({FaultBarrierInterceptor.class})
public class ShoppingCardServicesBean implements ShoppingCardServices { ...

This is an implementation of the Fault Barrier pattern.

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

Any runtime exception is catched, logged and a fault is signaled to the client (without internal details) using a TechnicalException. Checked exceptions are ignored.

捕获,记录任何运行时异常,并使用TechnicalException向客户端发出故障信号(没有内部详细信息)。检查的异常将被忽略。

RuntimeException handling is centralized and separated from any business methods.

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

#2


Any RuntimeException extends java.lang.Exception.

任何RuntimeException都会扩展java.lang.Exception。

The EJB spec provides handling for 2 types of exceptions (Application and System)

EJB规范提供了对两种类型的异常(应用程序和系统)的处理

If you'd like to throw a System Exception, you would usually do it like so:

如果您想抛出系统异常,通常会这样做:

try {
.... your code ...
}catch(YourApplicationException ae) {
   throw ae;
}catch(Exception e) {
   throw new EJBException(e); //here's where you need to change.
}

To hide the internal details of your system exception, simply replace:

要隐藏系统异常的内部详细信息,只需替换:

throw new EJBException(e); 

with:

throw new EJBException(new TechnicalException("Technical Fault"));

Hope this is what you were looking for.

希望这是你想要的。

Cheers

#1


Finally, based on previous answer and my personal researches, I retained the folowing solution.

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

I've created an interceptor dedicated to manage server faults :

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

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();
    }
}}

The thrown technical exception extends EJBException and does not expose the cause RuntimeException:

抛出的技术异常扩展了EJBException,并且没有暴露原因RuntimeException:

public class TechnicalException extends EJBException {}

I use this interceptor in all public services :

我在所有公共服务中使用这个拦截器:

@Stateless
@Interceptors({FaultBarrierInterceptor.class})
public class ShoppingCardServicesBean implements ShoppingCardServices { ...

This is an implementation of the Fault Barrier pattern.

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

Any runtime exception is catched, logged and a fault is signaled to the client (without internal details) using a TechnicalException. Checked exceptions are ignored.

捕获,记录任何运行时异常,并使用TechnicalException向客户端发出故障信号(没有内部详细信息)。检查的异常将被忽略。

RuntimeException handling is centralized and separated from any business methods.

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

#2


Any RuntimeException extends java.lang.Exception.

任何RuntimeException都会扩展java.lang.Exception。

The EJB spec provides handling for 2 types of exceptions (Application and System)

EJB规范提供了对两种类型的异常(应用程序和系统)的处理

If you'd like to throw a System Exception, you would usually do it like so:

如果您想抛出系统异常,通常会这样做:

try {
.... your code ...
}catch(YourApplicationException ae) {
   throw ae;
}catch(Exception e) {
   throw new EJBException(e); //here's where you need to change.
}

To hide the internal details of your system exception, simply replace:

要隐藏系统异常的内部详细信息,只需替换:

throw new EJBException(e); 

with:

throw new EJBException(new TechnicalException("Technical Fault"));

Hope this is what you were looking for.

希望这是你想要的。

Cheers