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