我正在使用HTTP和CXF组件在Mule ESB版本3.8中实现SOAP服务。请参阅附件中的流程设计图。
M子流为:
公共类AddValues { 私人诠释 私人int b; 公共setA(int a) { this.a = a; } 公共getA() { 返回 } 公共setB(int b) { this.b = b; } 公共getB() { 返回b; } }
使用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错误的最佳方法是什么吗?
答案 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的解决方案。 我的方法如下:
编写一个自定义转换器类,在其中添加验证规则。例如,如果我要为整数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());
}
}
到目前为止,这对我来说一直有效。 但是,如果有任何更好的解决方案,我将要求提出建议以改进此解决方案。
谢谢大家。