この問題も発生しました。私は、HTTP Invokerを介してSpring 3.1、JPA 2、およびHibernateをJPAプロバイダとして使用してデータベースにアクセスするサービスを公開しています。
問題を回避するために、私はカスタムインターセプターとWrappedExceptionという例外を書きました。インターセプタは、サービスによってスローされた例外をキャッチし、リフレクションおよびセッターを使用して例外および原因をWrappedExceptionに変換します。クライアントがクラスパスにWrappedExceptionを持っていると仮定すると、スタックトレースと元の例外クラス名はクライアントから見えます。
これは、クライアントがクラスパス上にSpring DAOを持つ必要性を緩和し、わかる限り、翻訳で元のスタックトレース情報は失われません。
インターセプタ
public class ServiceExceptionTranslatorInterceptor implements MethodInterceptor, Serializable {
private static final long serialVersionUID = 1L;
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
return invocation.proceed();
} catch (Throwable e) {
throw translateException(e);
}
}
static RuntimeException translateException(Throwable e) {
WrappedException serviceException = new WrappedException();
try {
serviceException.setStackTrace(e.getStackTrace());
serviceException.setMessage(e.getClass().getName() +
": " + e.getMessage());
getField(Throwable.class, "detailMessage").set(serviceException,
e.getMessage());
Throwable cause = e.getCause();
if (cause != null) {
getField(Throwable.class, "cause").set(serviceException,
translateException(cause));
}
} catch (IllegalArgumentException e1) {
// Should never happen, ServiceException is an instance of Throwable
} catch (IllegalAccessException e2) {
// Should never happen, we've set the fields to accessible
} catch (NoSuchFieldException e3) {
// Should never happen, we know 'detailMessage' and 'cause' are
// valid fields
}
return serviceException;
}
static Field getField(Class<?> clazz, String fieldName) throws NoSuchFieldException {
Field f = clazz.getDeclaredField(fieldName);
if (!f.isAccessible()) {
f.setAccessible(true);
}
return f;
}
}
例外
public class WrappedException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String message = null;
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return message;
}
}
豆配線
<bean id="exceptionTranslatorInterceptor" class="com.YOURCOMPANY.interceptor.ServiceExceptionTranslatorInterceptor"/>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="YOUR_SERVICE" />
<property name="order" value="1" />
<property name="interceptorNames">
<list>
<value>exceptionTranslatorInterceptor</value>
</list>
</property>
</bean>
完璧な、それは私が探していたものです。この問題でしばらく座った後、私はそれを処理するためにインターセプターが必要だと思ったが、決してコード化しなかった。ありがとう! –