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