Java 无CXF/Spring ws的驼峰返回简单SoapFault

Java 无CXF/Spring ws的驼峰返回简单SoapFault,java,web-services,soap,apache-camel,soapfault,Java,Web Services,Soap,Apache Camel,Soapfault,我创建了一个代理camel,它接受SOAP(通过HTTP)和RESTful请求,并将它们转发到正确的web服务。Camel不知道消息结构,它不知道WSDL或任何东西,它只是根据http头知道它是否是SOAP。没有CXF端点 此外,它还进行一些处理。异常可能发生在其中,例如,当找不到服务或url无效时。 有没有一种简单的方法可以直接从这个驼峰返回有效的SOAPFault? 我试着写一个简单的处理器,叫做OneException。看起来是这样的: .choice().when().header("S

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

此外,它还进行一些处理。异常可能发生在其中,例如,当找不到服务或url无效时。 有没有一种简单的方法可以直接从这个驼峰返回有效的SOAPFault? 我试着写一个简单的处理器,叫做OneException。看起来是这样的:

.choice().when().header("SOAP").processRef(ExceptionToSoapProcessor())
org.apache.cxf.binding.soap.SoapFault: Unauthorized
应该将任何异常转换为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);
}
(“未经授权”是实际消息)


PS:我以前使用过,但如前所述,我在这个Camel中没有任何ServiceInterface。

我会将错误场景的处理移动到一个块中。这样您就可以“声明”某些行为,比如将异常标记为已处理。IMHO让它更干净一点

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

java.lang.Exception
真的
公共静态字符串createSOAPFaultServerError(最终异常原因){
字符串结果=null;
错误(“创建SOAP错误,向客户端隐藏原始原因:”,原因);
试一试{
SOAPMessage message=MessageFactory.newInstance().createMessage();
SOAPEnvelope信封=message.getSOAPPart().getEnvelope();
SOAPBody=message.getSOAPBody();
SOAPFault fault=body.addFault();
setFaultCode(“服务器”);
setFaultString(“意外的服务器错误”);
Detail Detail=fault.addDetail();
Name entryName=envelope.createName(“消息”);
DetailEntry=detail.addDetailEntry(entryName);
entry.addTextNode(“服务器无法完成请求。内部错误”);
结果=SOAPMessage2字符串(消息);
}捕获(例外e){
LOG.error(“创建SOAP错误消息时出错”,e);
}
返回结果;
}
私有静态字符串soapMessage2String(最终SOAPMessage消息)引发SOAPException、IOException{
字符串结果=null;
ByteArrayOutputStream outStream=新建ByteArrayOutputStream();
消息写入(超出流);
结果=新字符串(outStream.toByteArray(),StandardCharsets.UTF_8);
返回结果;
}