java - 没有 CXF/Spring-ws 的 Camel 返回简单的 SoapFault

标签 java web-services soap apache-camel soapfault

我创建了一个代理 Camel ,它接受 SOAP(通过 HTTP)和 RESTful 请求并将它们转发到正确的 Web 服务。 Camel 不知道消息结构,它不知道 WSDL 或任何东西,它只根据 http header 知道它是否是 SOAP。没有 CXF 端点。

进一步它做一些处理。那里可能会发生异常,例如当找不到服务或 url 无效时。 有没有一种简单的方法可以直接从这只 Camel 返回有效的 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

(“未经授权”是实际消息)

PS:我用了dataformat SOAP之前,但如前所述,我在这个 Camel 中没有任何 ServiceInterface。

最佳答案

我会将错误场景的处理移至 onException()堵塞。这样你就可以“声明”一些行为,比如将异常标记为已处理。恕我直言,让它更干净一些。

仅仅返回 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

关于java - 没有 CXF/Spring-ws 的 Camel 返回简单的 SoapFault,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29679228/

相关文章:

java - 为什么如果我的文件名和公共(public)类名不同,我会收到编译错误?

c# - 通过 SOCKS5 代理连接到 .NET 网络服务

web-services - Java EE 中的 Web 服务身份验证

java - 避免 RPC (SOAP) API 之间的中间数据转换?

php - 向我们传输文件 NuSOAP

web-services - Swagger 可以用于 SOAP 吗?

java - 亚马逊 S3 集成

java - 如何使用变量名正确绘制矩形

java - Spark SQL Java GenericRowWithSchema 无法转换为 java.lang.String

python - SOAPpy 中的 namespace 未按预期工作