2017-02-13 11 views
0

私はすでにいくつかの時間を解決できないという問題があります。さらに、apache camelの新機能です。CamelからCXF SOAPサービスへの検証例外の受け渡し

私のシンプルなアプリケーションは、CXF(jettyをhttpエンジンとして使用)を使用してSOAP Webサービスを公開してから、soapリクエストがcamelを使用してakkaアクターに渡されます。

私は俳優への道で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)) 

} 

私はアプリを実行すると、私は(s「は$メッセージを返す」)ので、私は、ルートプロセッサを起動すると確信している、また俳優が呼び出されていないlog.infoからログを参照したがって、行:

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

は仕事をします。しかし、私のSOAPサービスは、障害情報の代わりに202 SUCCESSを返します。

答えて

1

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

を変更してみてください、あなたが探しているものですが、私は違っCXFエンドポイントの例外を処理しました。私は(等の検証エラーメッセージのような)のSOAPFaultにカスタムの詳細はHTTP-500を返すために持っていたので...

  1. 作成CXF .onException(classOf[PredicateValidationException]).handled(false)

  2. それを渡すためにキャメルで未処理の例外をキープorg.apache.cxf.interceptor.Fault Exceptionから必要なすべての詳細を持つオブジェクト。 (SOAPフォルトではない)。カスタムディテール要素、カスタムFaultCode要素、メッセージを設定することができます。最終的にはCXFエンドポイントからのメッセージを結果として生じることcxfFaultexchange.setProperty(Exchange.EXCEPTION_CAUGHT, cxfFault)

でExchange.EXCEPTION_CAUGHTプロパティを置き換える

  • はHTTP-500のSOAPFaultと、体内で、私はまだcxfFault

  • +0

    ありがとうございました。これは正確に私が求めていたものではありませんでしたが、あなたのアプローチはさらに優れています。 – dsinczak

    0

    キャメルは交換のインナー部分だけを見ていますが、アウト部分を変更しています。

    私はよく分からない

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

    いや、に設定された内容であります同じ。 Webサービスが返す202. – dsinczak

    +0

    私は、最初にあなたのカスタムエラーに本文を設定してから徐々に他のものを追加して、あなたのメッセージを乱しているかどうかを確認することをお勧めします。 – noMad17

    関連する問題