2017-02-13 59 views
0

我有一个问题,我已经解决了一段时间了,再加上我是新来的apache骆驼,它并没有帮助。将验证例外从驼峰传递到CXF SOAP服务

我的简单的应用程序公开使用CXF的SOAP Web服务(使用jetty作为http引擎),然后将soap请求传递给使用camel的akka​​ actors。

我想验证到演员的道路上的SOAP请求,并检查它是否包含某些标题和内容值。我不想使用CXF拦截器。问题是,在骆驼发生什么(异常,故障消息返回)不会传播到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“返回$消息”),所以我敢肯定,航线调用处理器,也是演员,则不会调用因此行:

exchange.getOut.setFault(true) 
exchange.getOut.setBody(message) 

做他们的工作。但是我的SOAP服务仍然返回202 SUCCESS而不是故障信息。

回答

1

我不知道是你在找什么,但是我处理了CXF端点例外不同。我只好跟在自定义的SOAPFault细节(如验证错误信息等)返回HTTP-500,所以...

  1. 保持异常未处理的骆驼将它传递给CXF .onException(classOf[PredicateValidationException]).handled(false)

  2. 创建org.apache.cxf.interceptor.Fault对象的所有需要​​的细节超出例外。 (不是SOAP错误)。它允许设置自定义细节元素,自定义FaultCode元素,消息。

  3. 最后用从CXF端点cxfFaultexchange.setProperty(Exchange.EXCEPTION_CAUGHT, cxfFault)

结果消息替换Exchange.EXCEPTION_CAUGHT属性是一个HTTP-500与的SOAPFault在体内与细节我在cxfFault

+0

非常感谢。这一个并不完全是我问的,但你的方法更好。 – dsinczak

0

骆驼只看着交易所的部分内容,但你正在修改外出部分。

尝试改变

exchange.getOut.setFault(true) 
exchange.getOut.setBody(message) 

exchange.getIn.setFault(true) 
exchange.getIn.setBody(message) 
+0

不,仍然是设定相同。 Web服务返回202. – dsinczak

+0

我建议您首先尝试将body设置为您的自定义错误,然后逐渐添加其他内容以查看与您的消息有关的内容。 – noMad17