代码之家  ›  专栏  ›  技术社区  ›  Karim Ahmed

将返回的SOAPFaultException重构为MyFaultException

  •  0
  • Karim Ahmed  · 技术社区  · 6 年前

    我现在在wss4j身份验证期间尝试更改返回的故障异常时遇到了一个问题。我成功地修改了故障体,可以向其添加详细信息,但返回给用户的异常仍然来自javax类型。xml。ws。肥皂SOAPFaultException,而不是我的新故障异常。

    当我从camel抛出故障异常,因为在路由过程中发生异常时,故障类型对我的故障异常是正确的,而不是javax。xml。ws。肥皂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);
        }
    
    }
    

    在客户端,接受包装的组织。阿帕奇。cxf。拦截器。安全CustomFaultOutInterceptor的身份验证异常

    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 回复  |  直到 6 年前
        1
  •  0
  •   Karim Ahmed    6 年前

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

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