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

时间:2019-01-25 07:36:04

标签: java soap fault mule-esb

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

M子流为:

  1. HTTP和CXF组件公开了提供两个整数之和的Web服务。发送请求的对象是:

公共类AddValues {     私人诠释     私人int b;     公共setA(int a)     {        this.a = a;     }     公共getA()     {         返回     }     公共setB(int b)     {         this.b = b;     }     公共getB()     {         返回b;     } }

  1. 使用变量保存SOAP操作。
  2. 基于SOAP Action路由的Flow控件。
  3. 使用JAVA转换器接收有效载荷并引发Custom Web Fault异常,如下所示:

    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;
    }
    

    }

但是我收到错误消息“尝试/捕获周围”

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

有人可以建议在Mule ESB中从JAVA Transformer发送自定义SOAP错误的最佳方法是什么吗?

2 个答案:

答案 0 :(得分:0)

您应该创建自己的SOAP Fault(纯Java字符串)并将其作为消息返回。如果需要,您还可以创建一个转换器并将其放在catch-exception-strategy中,如下所示:

@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;
}

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

答案 1 :(得分:0)

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

  1. 编写一个自定义转换器类,在其中添加验证规则。例如,如果我要为整数a或b为null抛出错误,我将使用以下代码添加自定义转换器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());
    }   
} 

到目前为止,这对我来说一直有效。 但是,如果有任何更好的解决方案,我将要求提出建议以改进此解决方案。

谢谢大家。