将返回的 SOAPFaultException 重构为 MyFaultException
Refactor the returned SOAPFaultException to MyFaultException
我现在在尝试更改 wss4j 身份验证期间返回的错误异常时遇到问题。我成功地更改了错误主体,我可以向它添加详细信息,但返回给用户的异常仍然来自 javax.xml.ws.soap.SOAPFaultException 类型,而不是我的新错误异常。
当我从 camel 抛出我的故障异常时,因为在路由期间发生异常,故障类型对我的故障异常是正确的,而不是 javax.xml.ws.soap.SOAPFaultException,所以请让我知道是否有办法改变默认行为.
public class CustomFaultOutInterceptor extends FaultOutInterceptor {
private static final transient Logger LOG = LoggerFactory.getLogger(CustomFaultOutInterceptor.class);
@Override
public void handleMessage(Message message) throws Fault {
LOG.info(" >> Problem occurred during handling the request/response message");
//Get the original exception from the fault exception
Throwable callingServiceException = message.getContent(Exception.class);
String faultString = null;
FaultMessageEnum faultMessage = FaultMessageEnum.UN_DEFINED_ERROR;
boolean isFaultExceptionNotFromTypeMyFaultException = false; //from camel route error handler
boolean isFaultExceptionUnDefined = false;
if(callingServiceException.getCause() != null) {
if (callingServiceException.getCause() instanceof org.apache.wss4j.common.ext.WSSecurityException) {
// Wrong header format or time-stamp
faultMessage = FaultMessageEnum.MESSAGE_FORMAT_OR_TIMESTAMP_EXCEPTION;
faultString = faultMessage.errorMessage();
isFaultExceptionNotFromTypeMyFaultException = true;
} else if (callingServiceException.getCause() instanceof org.apache.cxf.interceptor.security.AuthenticationException) {
// Wrong User-name/Password
faultMessage = FaultMessageEnum.AUTHENTICATION_FAILED_ERROR;
faultString = faultMessage.errorMessage();
isFaultExceptionNotFromTypeMyFaultException = true;
} else if (callingServiceException.getCause() instanceof org.apache.cxf.interceptor.security.AccessDeniedException) {
// Unauthorized Access
faultMessage = FaultMessageEnum.AUTHORIZATION_FAILED_ERROR;
faultString = faultMessage.errorMessage();
isFaultExceptionNotFromTypeMyFaultException = true;
} else if (callingServiceException.getCause() instanceof MyFaultException) {
faultString = convertObjectToJSON(((MyFaultException)callingServiceException.getCause()).getFaultInfo());
}
}
if (faultString == null) {
isFaultExceptionUnDefined = true;
isFaultExceptionNotFromTypeMyFaultException = true;
while(callingServiceException.getCause() != null) { //Get the actual exception
callingServiceException = callingServiceException.getCause();
}
faultString = "{\"faultString\":\"" + callingServiceException.getMessage() + "\",\"cause\":\""
+ callingServiceException.getClass().getCanonicalName() + "\"}";
}
// Wrap the fault exception to MyFaultException if isFaultExceptionNotFromTypeMyFaultException = true
if (isFaultExceptionNotFromTypeMyFaultException ) {
// Alter the fault exception to MyFaultException
SimpleExceptionBean wrappedException = new SimpleExceptionBean(faultMessage.getType(), faultMessage.getCode(), faultMessage.getDescription());
MyFaultException newException = null;
if(isFaultExceptionUnDefined)
newException = new MyFaultException(callingServiceException.getMessage(), wrappedException, callingServiceException);
else
newException = new MyFaultException(faultMessage.getDescription(), wrappedException, callingServiceException);
Fault newfault = new Fault(newException, new QName(faultMessage.getType()));
/*try {
JAXBDataBinding binding = new JAXBDataBinding(SimpleExceptionBean.class);
DataWriterImpl<Element> writer = new DataWriterImpl<Element>(binding);
writer.write(wrappedException, null, newfault.getOrCreateDetail());
} catch (JAXBException e) {
LOG.error(e.getMessage());
} */
message.setContent(Exception.class, newfault);
}
}
在客户端,CustomFaultOutInterceptor
包装 org.apache.cxf.interceptor.security.AuthenticationException
javax.xml.ws.soap.SOAPFaultException: Wrong Authentication Credentials.
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
at com.sun.proxy.$Proxy33.getCarInfoByPlate(Unknown Source)
at com.mycompany.integration.elm.client.wsservice.TestWebService.main(TestWebService.java:49)
Caused by: org.apache.cxf.binding.soap.SoapFault: Wrong Authentication Credentials.
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:86)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:52)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:41)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:112)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:801)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1672)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1551)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1348)
at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:216)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:651)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:324)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:277)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
我没有得到直接的解决方案。我通过如下构建故障的详细对象手册来解决它:
// Build Fault Message Detail
Document newDoc = DOMUtils.createDocument();
Element exceptionDetail = newDoc.createElement("detail");
Element esbFaultNode = newDoc.createElement(newException.getClass().getSimpleName());
exceptionDetail.appendChild(esbFaultNode);
Element faultTypeBeanNode = newDoc.createElement("ErrorType");
faultTypeBeanNode.setTextContent(newFaultExceptionbean.getType().name());
Element faultCodeBeanNode = newDoc.createElement("ErrorCode");
faultCodeBeanNode.setTextContent(newFaultExceptionbean.getCode().toString());
Element faultMessageBeanNode = newDoc.createElement("ErrorMessage");
faultMessageBeanNode.setTextContent(newFaultExceptionbean.getMessage());
esbFaultNode.appendChild(faultTypeBeanNode);
esbFaultNode.appendChild(faultCodeBeanNode);
esbFaultNode.appendChild(faultMessageBeanNode);
// Set the fault detail
newfault.setDetail(exceptionDetail);`
我现在在尝试更改 wss4j 身份验证期间返回的错误异常时遇到问题。我成功地更改了错误主体,我可以向它添加详细信息,但返回给用户的异常仍然来自 javax.xml.ws.soap.SOAPFaultException 类型,而不是我的新错误异常。
当我从 camel 抛出我的故障异常时,因为在路由期间发生异常,故障类型对我的故障异常是正确的,而不是 javax.xml.ws.soap.SOAPFaultException,所以请让我知道是否有办法改变默认行为.
public class CustomFaultOutInterceptor extends FaultOutInterceptor {
private static final transient Logger LOG = LoggerFactory.getLogger(CustomFaultOutInterceptor.class);
@Override
public void handleMessage(Message message) throws Fault {
LOG.info(" >> Problem occurred during handling the request/response message");
//Get the original exception from the fault exception
Throwable callingServiceException = message.getContent(Exception.class);
String faultString = null;
FaultMessageEnum faultMessage = FaultMessageEnum.UN_DEFINED_ERROR;
boolean isFaultExceptionNotFromTypeMyFaultException = false; //from camel route error handler
boolean isFaultExceptionUnDefined = false;
if(callingServiceException.getCause() != null) {
if (callingServiceException.getCause() instanceof org.apache.wss4j.common.ext.WSSecurityException) {
// Wrong header format or time-stamp
faultMessage = FaultMessageEnum.MESSAGE_FORMAT_OR_TIMESTAMP_EXCEPTION;
faultString = faultMessage.errorMessage();
isFaultExceptionNotFromTypeMyFaultException = true;
} else if (callingServiceException.getCause() instanceof org.apache.cxf.interceptor.security.AuthenticationException) {
// Wrong User-name/Password
faultMessage = FaultMessageEnum.AUTHENTICATION_FAILED_ERROR;
faultString = faultMessage.errorMessage();
isFaultExceptionNotFromTypeMyFaultException = true;
} else if (callingServiceException.getCause() instanceof org.apache.cxf.interceptor.security.AccessDeniedException) {
// Unauthorized Access
faultMessage = FaultMessageEnum.AUTHORIZATION_FAILED_ERROR;
faultString = faultMessage.errorMessage();
isFaultExceptionNotFromTypeMyFaultException = true;
} else if (callingServiceException.getCause() instanceof MyFaultException) {
faultString = convertObjectToJSON(((MyFaultException)callingServiceException.getCause()).getFaultInfo());
}
}
if (faultString == null) {
isFaultExceptionUnDefined = true;
isFaultExceptionNotFromTypeMyFaultException = true;
while(callingServiceException.getCause() != null) { //Get the actual exception
callingServiceException = callingServiceException.getCause();
}
faultString = "{\"faultString\":\"" + callingServiceException.getMessage() + "\",\"cause\":\""
+ callingServiceException.getClass().getCanonicalName() + "\"}";
}
// Wrap the fault exception to MyFaultException if isFaultExceptionNotFromTypeMyFaultException = true
if (isFaultExceptionNotFromTypeMyFaultException ) {
// Alter the fault exception to MyFaultException
SimpleExceptionBean wrappedException = new SimpleExceptionBean(faultMessage.getType(), faultMessage.getCode(), faultMessage.getDescription());
MyFaultException newException = null;
if(isFaultExceptionUnDefined)
newException = new MyFaultException(callingServiceException.getMessage(), wrappedException, callingServiceException);
else
newException = new MyFaultException(faultMessage.getDescription(), wrappedException, callingServiceException);
Fault newfault = new Fault(newException, new QName(faultMessage.getType()));
/*try {
JAXBDataBinding binding = new JAXBDataBinding(SimpleExceptionBean.class);
DataWriterImpl<Element> writer = new DataWriterImpl<Element>(binding);
writer.write(wrappedException, null, newfault.getOrCreateDetail());
} catch (JAXBException e) {
LOG.error(e.getMessage());
} */
message.setContent(Exception.class, newfault);
}
}
在客户端,CustomFaultOutInterceptor
包装 org.apache.cxf.interceptor.security.AuthenticationExceptionjavax.xml.ws.soap.SOAPFaultException: Wrong Authentication Credentials.
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
at com.sun.proxy.$Proxy33.getCarInfoByPlate(Unknown Source)
at com.mycompany.integration.elm.client.wsservice.TestWebService.main(TestWebService.java:49)
Caused by: org.apache.cxf.binding.soap.SoapFault: Wrong Authentication Credentials.
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:86)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:52)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:41)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:112)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:801)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1672)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1551)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1348)
at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:216)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:651)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:324)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:277)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
我没有得到直接的解决方案。我通过如下构建故障的详细对象手册来解决它:
// Build Fault Message Detail
Document newDoc = DOMUtils.createDocument();
Element exceptionDetail = newDoc.createElement("detail");
Element esbFaultNode = newDoc.createElement(newException.getClass().getSimpleName());
exceptionDetail.appendChild(esbFaultNode);
Element faultTypeBeanNode = newDoc.createElement("ErrorType");
faultTypeBeanNode.setTextContent(newFaultExceptionbean.getType().name());
Element faultCodeBeanNode = newDoc.createElement("ErrorCode");
faultCodeBeanNode.setTextContent(newFaultExceptionbean.getCode().toString());
Element faultMessageBeanNode = newDoc.createElement("ErrorMessage");
faultMessageBeanNode.setTextContent(newFaultExceptionbean.getMessage());
esbFaultNode.appendChild(faultTypeBeanNode);
esbFaultNode.appendChild(faultCodeBeanNode);
esbFaultNode.appendChild(faultMessageBeanNode);
// Set the fault detail
newfault.setDetail(exceptionDetail);`