骆驼 return 没有 CXF/Spring-ws 的简单 SoapFault
Camel return simple SoapFault without CXF/Spring-ws
我创建了一个 proxy-camel 接受 SOAP(通过 HTTP)和 RESTful 请求并将它们转发到正确的 Web 服务。 Camel 不知道 message-structure,它不知道 WSDL 或任何东西,它只根据 http header 知道它是否是 SOAP。没有 CXF 端点。
此外它还做了一些处理。那里可能会发生异常,例如当找不到服务或 url 无效时。
有直接从这只骆驼 return 一个有效的 SOAPFault 的简单方法吗?
我尝试编写一个简单的处理器,称为 onException。它看起来像这样:
.choice().when().header("SOAP").processRef(ExceptionToSoapProcessor())
应该将任何异常转换为 SOAPFault 的处理器如下所示
@Override
public void process(Exchange exchange) throws Exception {
Exception exception = (Exception) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
Integer responseCode = (Integer) exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE);
QName qName = SoapFault.FAULT_CODE_SERVER;
if (responseCode != null && responseCode < 500) {
qName = SoapFault.FAULT_CODE_CLIENT;
}
SoapFault fault = new SoapFault(exception.getMessage(), qName);
Message outMessage = exchange.getOut();
outMessage.setHeader(Message.RESPONSE_CODE, 500);
outMessage.setFault(true);
outMessage.setBody(fault);
exchange.setException(null);
exchange.removeProperty(Exchange.EXCEPTION_CAUGHT);
exchange.setProperty(Exchange.EXCEPTION_HANDLED, true);
}
但现在我不明白我将如何编组它,响应看起来像这样:
org.apache.cxf.binding.soap.SoapFault: Unauthorized
("Unauthorized" 是实际消息)
PS: 我之前使用的是dataformat SOAP,但是如前所述,我在这个Camel中没有任何ServiceInterface。
我会将错误场景的处理移至 onException() 块。这样你就可以 "declare" 一些行为,比如将异常标记为已处理。恕我直言,让它更干净一些。
仅返回 SOAP 错误不会产生有效的 SOAP 响应。您必须构建完整的消息结构。我认为没有将 SOAP 消息转换为文本流的类型转换器,因此您必须自己编组 SOAP 响应。
这是我用来完成这项工作的代码:
<onException>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<bean beanType="some.package.WSHelper" method="createSOAPFaultServerError" />
</onException>
public static String createSOAPFaultServerError(final Exception cause) {
String result = null;
LOG.error("Creating SOAP fault, hiding original cause from client:", cause);
try {
SOAPMessage message = MessageFactory.newInstance().createMessage();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
SOAPBody body = message.getSOAPBody();
SOAPFault fault = body.addFault();
fault.setFaultCode("Server");
fault.setFaultString("Unexpected server error.");
Detail detail = fault.addDetail();
Name entryName = envelope.createName("message");
DetailEntry entry = detail.addDetailEntry(entryName);
entry.addTextNode("The server is not able to complete the request. Internal error.");
result = soapMessage2String(message);
} catch (Exception e) {
LOG.error("Error creating SOAP Fault message", e);
}
return result;
}
private static String soapMessage2String(final SOAPMessage message) throws SOAPException, IOException {
String result = null;
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
message.writeTo(outStream);
result = new String(outStream.toByteArray(), StandardCharsets.UTF_8);
return result;
}
HTH
我创建了一个 proxy-camel 接受 SOAP(通过 HTTP)和 RESTful 请求并将它们转发到正确的 Web 服务。 Camel 不知道 message-structure,它不知道 WSDL 或任何东西,它只根据 http header 知道它是否是 SOAP。没有 CXF 端点。
此外它还做了一些处理。那里可能会发生异常,例如当找不到服务或 url 无效时。 有直接从这只骆驼 return 一个有效的 SOAPFault 的简单方法吗? 我尝试编写一个简单的处理器,称为 onException。它看起来像这样:
.choice().when().header("SOAP").processRef(ExceptionToSoapProcessor())
应该将任何异常转换为 SOAPFault 的处理器如下所示
@Override
public void process(Exchange exchange) throws Exception {
Exception exception = (Exception) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
Integer responseCode = (Integer) exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE);
QName qName = SoapFault.FAULT_CODE_SERVER;
if (responseCode != null && responseCode < 500) {
qName = SoapFault.FAULT_CODE_CLIENT;
}
SoapFault fault = new SoapFault(exception.getMessage(), qName);
Message outMessage = exchange.getOut();
outMessage.setHeader(Message.RESPONSE_CODE, 500);
outMessage.setFault(true);
outMessage.setBody(fault);
exchange.setException(null);
exchange.removeProperty(Exchange.EXCEPTION_CAUGHT);
exchange.setProperty(Exchange.EXCEPTION_HANDLED, true);
}
但现在我不明白我将如何编组它,响应看起来像这样:
org.apache.cxf.binding.soap.SoapFault: Unauthorized
("Unauthorized" 是实际消息)
PS: 我之前使用的是dataformat SOAP,但是如前所述,我在这个Camel中没有任何ServiceInterface。
我会将错误场景的处理移至 onException() 块。这样你就可以 "declare" 一些行为,比如将异常标记为已处理。恕我直言,让它更干净一些。
仅返回 SOAP 错误不会产生有效的 SOAP 响应。您必须构建完整的消息结构。我认为没有将 SOAP 消息转换为文本流的类型转换器,因此您必须自己编组 SOAP 响应。
这是我用来完成这项工作的代码:
<onException>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<bean beanType="some.package.WSHelper" method="createSOAPFaultServerError" />
</onException>
public static String createSOAPFaultServerError(final Exception cause) {
String result = null;
LOG.error("Creating SOAP fault, hiding original cause from client:", cause);
try {
SOAPMessage message = MessageFactory.newInstance().createMessage();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
SOAPBody body = message.getSOAPBody();
SOAPFault fault = body.addFault();
fault.setFaultCode("Server");
fault.setFaultString("Unexpected server error.");
Detail detail = fault.addDetail();
Name entryName = envelope.createName("message");
DetailEntry entry = detail.addDetailEntry(entryName);
entry.addTextNode("The server is not able to complete the request. Internal error.");
result = soapMessage2String(message);
} catch (Exception e) {
LOG.error("Error creating SOAP Fault message", e);
}
return result;
}
private static String soapMessage2String(final SOAPMessage message) throws SOAPException, IOException {
String result = null;
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
message.writeTo(outStream);
result = new String(outStream.toByteArray(), StandardCharsets.UTF_8);
return result;
}
HTH