如何从 Mule ESB 3.8 中的 JAVA Transformer 内部抛出自定义异常?
How to throw a custom exception from inside JAVA Transformer in Mule ESB 3.8?
我正在使用 HTTP 和 CXF 组件在 Mule ESB 3.8 版中实现 SOAP 服务。流程设计见附图
Mule 流程是:
- HTTP 和 CXF 组件公开提供两个整数之和的 Web 服务。请求发送的对象是:
public class 添加值{
私人诠释;
私人诠释 b;
public setA(int a)
{
this.a =一个;
}
public getA()
{
return一个;
}
public setB(int b)
{
this.b =b;
}
public getB()
{
return b;
}
}
- 使用变量保存 SOAP 操作。
- 基于 SOAP Action 路由流控制。
使用JAVA转换器接收payload并抛出Custom 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;
}
}
但我收到错误 "Surround with try/catch"
我的问题是,如果我包围并处理异常,我将如何将 SOAP 错误发送给最终用户?
有人可以建议从 Mule ESB 中的 JAVA Transformer 发送自定义 SOAP 错误的最佳方法是什么吗?
您应该创建自己的 SOAP Fault(纯 Java 字符串)并将其 return 作为消息。如果需要,您还可以创建一个转换器并将其放入您的 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 设置你自己的异常作为原因。
我找到了一个使用 TransformerException 和 CXF OutFaultInterceptor 的解决方案。
我的做法如下:
编写自定义转换器 class,在其中添加验证规则。例如,如果我想为整数 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());
}
}
目前这对我有用。
但是,如果有更好的解决方案,我会请求改进此解决方案的建议。
谢谢大家
我正在使用 HTTP 和 CXF 组件在 Mule ESB 3.8 版中实现 SOAP 服务。流程设计见附图
Mule 流程是:
- HTTP 和 CXF 组件公开提供两个整数之和的 Web 服务。请求发送的对象是:
public class 添加值{ 私人诠释; 私人诠释 b; public setA(int a) { this.a =一个; } public getA() { return一个; } public setB(int b) { this.b =b; } public getB() { return b; } }
- 使用变量保存 SOAP 操作。
- 基于 SOAP Action 路由流控制。
使用JAVA转换器接收payload并抛出Custom 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; }
}
但我收到错误 "Surround with try/catch"
我的问题是,如果我包围并处理异常,我将如何将 SOAP 错误发送给最终用户?
有人可以建议从 Mule ESB 中的 JAVA Transformer 发送自定义 SOAP 错误的最佳方法是什么吗?
您应该创建自己的 SOAP Fault(纯 Java 字符串)并将其 return 作为消息。如果需要,您还可以创建一个转换器并将其放入您的 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 设置你自己的异常作为原因。
我找到了一个使用 TransformerException 和 CXF OutFaultInterceptor 的解决方案。 我的做法如下:
编写自定义转换器 class,在其中添加验证规则。例如,如果我想为整数 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());
}
}
目前这对我有用。 但是,如果有更好的解决方案,我会请求改进此解决方案的建议。
谢谢大家