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