Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Mule ESB 3.8中从JAVA Transformer内部抛出自定义异常?_Java_Soap_Fault_Mule Esb - Fatal编程技术网

如何在Mule ESB 3.8中从JAVA Transformer内部抛出自定义异常?

如何在Mule ESB 3.8中从JAVA Transformer内部抛出自定义异常?,java,soap,fault,mule-esb,Java,Soap,Fault,Mule Esb,我正在使用HTTP和CXF组件在Mule ESB版本3.8中实现SOAP服务。有关流程设计,请参见附图 Mule流程为: HTTP和CXF组件公开提供两个整数之和的web服务。发送请求的对象是: 公共类addValue{ 私人INTA; 私人INTB; 公共setA(INTA) { 这个a=a; } 公共getA() { 返回a; } 公共教育部(int b) { 这个.b=b; } 公共getB() { 返回b; } } 使用变量保存SOAP操作 基于SOAP操作路由流控制 使用JAVA tr

我正在使用HTTP和CXF组件在Mule ESB版本3.8中实现SOAP服务。有关流程设计,请参见附图

Mule流程为:

  • HTTP和CXF组件公开提供两个整数之和的web服务。发送请求的对象是:
  • 公共类addValue{ 私人INTA; 私人INTB; 公共setA(INTA) { 这个a=a; } 公共getA() { 返回a; } 公共教育部(int b) { 这个.b=b; } 公共getB() { 返回b; } }

  • 使用变量保存SOAP操作
  • 基于SOAP操作路由流控制
  • 使用JAVA transformer接收负载并引发自定义Web故障异常,如下所示:

    public class AddValuesBusinessLogic extends AbstractMessageTransformer 
    {
        @Override
        public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
        MuleMessage muleMessage = message;
        AddValues addValues = (AddValues) muleMessage.getPayload();
        if (addValues.getA() == null || addValues.getB() == null ) {
            //Make an AddValueException object
            throw new Exception("Add value exception");
        }
        return null;
    }
    
    }

  • 但我得到的错误是“用try/catch包围”

    我的问题是,如果我包围并处理异常,我将如何将SOAP错误发送给最终用户


    有人能建议一下从Mule ESB中的JAVA Transformer发送自定义SOAP错误的最佳方式吗?

    您应该创建自己的SOAP错误(纯JAVA字符串)并将其作为消息返回。如果需要,还可以创建一个转换器,并将其放入
    捕获异常策略中,如下所示:

    @Override
    public Object transformMessage(MuleMessage message, String outputEncoding)
        throws TransformerException {
    
        String exceptionMessage = message.getExceptionPayload().getException().getCause().getMessage();        
    
        String outputMessage = "<soap:Fault xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">        " +
            " <faultcode>soap:Server</faultcode> " +
            "<faultstring>" + exceptionMessage + "</faultstring>" +
            "</soap:Fault>";
    
        return outputMessage;
    }
    
    @覆盖
    公共对象转换消息(多消息消息、字符串输出编码)
    抛出TransformerException{
    字符串exceptionMessage=message.getExceptionPayload().getException().getCause().getMessage();
    String outputMessage=“”+
    “soap:服务器”+
    “”+例外消息+“”+
    "";
    返回输出消息;
    }
    

    Mule总是希望异常被封装在TransformerException中,因此您应该抛出一个新的TransformerException,将您自己的异常设置为原因。

    我找到了一个使用TransformerException和CXF OutFaultInterceptor的解决方案。 我的做法如下:

    public class AddValuesBusinessLogic extends AbstractMessageTransformer 
    {
        @Override
        public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
        MuleMessage muleMessage = message;
        AddValues addValues = (AddValues) muleMessage.getPayload();
        if (addValues.getA() == null || addValues.getB() == null ) {
            //Make an AddValueException object
            throw new Exception("Add value exception");
        }
        return null;
    }
    
  • 编写一个自定义transformer类,在其中添加验证规则。例如,如果我想对为null的整数a或b抛出错误,我将使用以下代码添加自定义转换器AddValuesBusinessLogic.class:

    public class AddValuesBusinessLogic extends AbstractMessageTransformer 
    {
        @Override
        public Object transformMessage(MuleMessage message, String outputEncoding) throws 
        TransformerException 
        {
            MuleMessage muleMessage = message;
            AddValues addValues = (AddValues) muleMessage.getPayload();
            if (addValues.getA() == null || addValues.getB() == null ) {
            //Make an AddValueException object
            throw new TransformerException(this,new AddValueException("BAD REQUEST"));
        }
        return "ALL OK";}
    
  • 然后,此异常将传播到CXF,我在其中编写一个OutFaultInterceptor,如下所示:

    public class AddValuesFaultInterceptor extends AbstractSoapInterceptor {
    
        private static final Logger logger = LoggerFactory.getLogger(AddValuesFaultInterceptor.class);
    
        public AddValuesFaultInterceptor() {
            super(Phase.MARSHAL);
        }
    
        public void handleMessage(SoapMessage soapMessage) throws Fault {
            Fault fault = (Fault) soapMessage.getContent(Exception.class);
    
            if (fault.getCause() instanceof org.mule.api.transformer.TransformerMessagingException) {           
                Element detail = fault.getOrCreateDetail();
                Element errorDetail = detail.getOwnerDocument().createElement("addValuesError");
                Element errorCode = errorDetail.getOwnerDocument().createElement("errorCode");
                Element message = errorDetail.getOwnerDocument().createElement("message");
                errorCode.setTextContent("400");
                message.setTextContent("BAD REQUEST");
                errorDetail.appendChild(errorCode);
                errorDetail.appendChild(message);
                detail.appendChild(errorDetail);
            }
        }
        private Throwable getOriginalCause(Throwable t) {
            if (t instanceof ComponentException && t.getCause() != null) {
                return t.getCause();
            } else {
                return t;
            }
        }
    }
    
    现在,当我使用SOAPUI或jaxws客户机进行调用时,我会在SOAP响应中得到自定义故障异常

    要在JAXWS客户端中提取errorCode和errorMessage的值,我在try-catch的catch块中执行以下操作:

    catch (com.sun.xml.ws.fault.ServerSOAPFaultException soapFaultException) {
    
        javax.xml.soap.SOAPFault fault = soapFaultException.getFault(); // <Fault> node
        javax.xml.soap.Detail detail = fault.getDetail(); // <detail> node
        java.util.Iterator detailEntries = detail.getDetailEntries(); // nodes under <detail>'
        while(detailEntries.hasNext()) {
            javax.xml.soap.DetailEntry detailEntry = (DetailEntry) detailEntries.next();
            System.out.println(detailEntry.getFirstChild().getTextContent());
            System.out.println(detailEntry.getLastChild().getTextContent());
        }   
    } 
    
    catch(com.sun.xml.ws.fault.ServerSOAPFaultException soapFaultException){
    javax.xml.soap.SOAPFault fault=soapFaultException.getFault();//节点
    javax.xml.soap.Detail Detail=fault.getDetail();//节点
    java.util.Iterator detailEntries=detail.getDetailEntries();//下的节点'
    while(detailEntries.hasNext()){
    javax.xml.soap.DetailEntry DetailEntry=(DetailEntry)detailEntries.next();
    System.out.println(detailEntry.getFirstChild().getTextContent());
    System.out.println(detailEntry.getLastChild().getTextContent());
    }   
    } 
    
    到目前为止,这对我是有效的。 然而,我会要求建议改进这项工作,或者是否有更好的解决方案


    谢谢大家。

    Hello@gbandres我尝试实现您的答案,但有两个问题。。1.输出消息在SOAP服务器故障中作为CDATA返回。2.我想为特定服务创建fault对象,并将此故障作为未发生的异常抛出。我使用了您的指导原则“Mule始终希望异常封装在TransformerException中,因此您应该抛出一个新的TransformerException,将您自己的异常设置为原因”,从而提出了上述解决方法。谢谢你的帮助。