이 문제도 발생했습니다. 나는 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>
내가보기에 완벽 했어. 이 문제로 잠시 앉아서 인터셉터를 처리 할 필요가 있지만 결코 코딩 할 필요가 없다는 것을 알았습니다. 감사! –