我也遇到過這個問題;我通過使用Spring 3.1,JPA 2和Hibernate作爲JPA提供者訪問數據庫的HTTP Invoker公開了一個服務。
要解決這個問題,我寫了一個自定義的攔截器和一個名爲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>
完美,這就是我一直在尋找。這個問題坐了一會兒後,我想,我需要一個攔截器來處理它,但從來沒有編碼。謝謝! – 2012-04-30 18:07:08