我有一个问题,我已经解决了一段时间了,加上我对apache camel的新手并没有帮助。
我的简单应用程序使用CXF(使用jetty作为http引擎)公开SOAP Web服务,然后使用camel将soap请求传递给akka actor。
我想在前往actor的路上验证SOAP请求,并检查它是否包含某些标头和内容值。我不想使用CXF拦截器。问题是,camel中发生的事情(例外,故障消息返回)不会传播到cxf。我总是将SUCCESS 202作为响应和有关日志中验证异常的信息。
这是我的简单应用:
class RequestActor extends Actor with WithLogger {
def receive = {
case CamelMessage(body: Request, headers) =>
logger.info(s"Received Request $body [$headers]")
case msg: CamelMessage =>
logger.error(s"unknown message ${msg.body}")
}
}
class CustomRouteBuilder(endpointUrl: String, serviceClassPath: String, system: ActorSystem)
extends RouteBuilder {
def configure {
val requestActor = system.actorOf(Props[RequestActor])
from(s"cxf:${endpointUrl}?serviceClass=${serviceClassPath}")
.onException(classOf[PredicateValidationException])
.handled(true)
.process(new Processor {
override def process(exchange: Exchange): Unit = {
val message = MessageFactory.newInstance().createMessage();
val envelope = message.getSOAPPart().getEnvelope();
val body = message.getSOAPBody();
val fault = body.addFault();
fault.setFaultCode("Server");
fault.setFaultString("Unexpected server error.");
val detail = fault.addDetail();
val entryName = envelope.createName("message");
val entry = detail.addDetailEntry(entryName);
entry.addTextNode("The server is not able to complete the request. Internal error.");
log.info(s"Returning $message")
exchange.getOut.setFault(true)
exchange.getOut.setBody(message)
}
})
.end()
.validate(header("attribute").isEqualTo("for_sure_not_defined"))
.to(genericActor)
}
}
object Init extends App {
implicit val system = ActorSystem("superman")
val camel = CamelExtension(system)
val camelContext = camel.context
val producerTemplate = camel.template
val endpointClassPath = classOf[Service].getName
val endpointUrl = "http://localhost:1234/endpoint"
camel.context.addRoutes(new CustomRouteBuilder(endpointUrl, endpointClassPath, system))
}
当我运行应用程序时,我会看到来自log.info的日志(s"返回$ message")所以我确定路由调用处理器,因此也没有调用actor:
exchange.getOut.setFault(true)
exchange.getOut.setBody(message)
做他们的工作。但我的SOAP服务仍然返回202 SUCCESS而不是故障信息。
答案 0 :(得分:1)
我不确定您在寻找什么,但我以不同方式处理了CXF端点的例外情况。我不得不在SOAPFault中返回带有自定义详细信息的HTTP-500(如验证错误消息等),所以......
保持异常未被Camel处理以将其传递给CXF .onException(classOf[PredicateValidationException]).handled(false)
使用Exception中的所有必需详细信息创建org.apache.cxf.interceptor.Fault
对象。 (不是SOAP Fault)。它允许设置自定义详细信息元素,自定义FaultCode元素,消息。
最后用cxfFault
exchange.setProperty(Exchange.EXCEPTION_CAUGHT, cxfFault)
来自CXF Endpoint的结果消息是一个带有SOAPFault的HTTP-500,其中包含我在cxfFault
中设置的详细信息
答案 1 :(得分:0)
Camel只关注交易所的部分内容,但您正在修改外部部分。
尝试更改
exchange.getOut.setFault(true)
exchange.getOut.setBody(message)
到
exchange.getIn.setFault(true)
exchange.getIn.setBody(message)