将返回的SOAPFaultException重构为MyFaultException

时间:2018-03-14 09:31:29

标签: java apache-camel cxf

我在尝试在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)

1 个答案:

答案 0 :(得分:0)

我没有得到直接解决方案。我通过构建故障'详细对象手册解决了它,如下所示:

        // 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);`