如何在Mule ESB 3.8中从JAVA Transformer内部抛出自定义异常?
我正在使用HTTP和CXF组件在Mule ESB版本3.8中实现SOAP服务。有关流程设计,请参见附图 Mule流程为:如何在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
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;
}
}有人能建议一下从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,将您自己的异常设置为原因”,从而提出了上述解决方法。谢谢你的帮助。