2017-05-10 47 views
0

我在我的應用程序如下路線:如何在Akka Scala中設置HttpResponse中的Set-Cookie頭?

val myRoute = Route { context => 

     val handler = Source.single(getRequest(context)) 
      .via(flow(server, port)) 
      .runWith(Sink.head).flatMap { r => 

      // Add cookie to response depending on certain preconditions 

     context.complete(r) 

     } 

} 

我的問題是,我不能使用外的開箱setCookie法(?或可我),因爲我是一個路線內,所以我會得到一個類型錯誤。我想過在HttpResponse(在r以上的例子中)手動添加一個頭元素,但這非常麻煩。

任何想法如何輕鬆地添加Set-Cookie標題元素?

回答

2

setCookie方法指令

一個Route只是​​:(RequestContext) => Future[RouteResult]。因此,您可以使用函數組合將cookie添加到來自下游服務的HttpResponse

首先創建使用預定義流程的轉發器:

val forwardRequest : HttpRequest => Future[HttpResponse] = 
    Source 
    .single(_) 
    .via(flow(server, port)) 
    .runWith(Sink.head) 

然後撰寫該功能與getRequest和轉換器從HttpResponseRouteResult

val queryExternalService : Route = 
    getRequest andThen forwardRequest andThen (_ map RouteResult.Complete) 

最後,設置cookie:

val httpCookie : HttpCookie = ??? //not specified in question 

val myRoute : Route = setCookie(httpCookie)(queryExternalService) 

手冊附錄中的路線

您可以手動設置Cookie:

val updateHeaders : (HttpHeader) => (HttpResponse) => HttpResponse = 
    (newHeader) => 
    (httpResponse) => 
     httpResponse withHeaders { 
     Some(httpResponse.headers.indexWhere(_.name equalsIgnoreCase newHeader.name)) 
      .filter(_ >= 0) 
      .map(index => httpResponse.headers updated (index, newHeader)) 
      .getOrElse(httpResponse.headers +: newHeader) 
     } 
... 
.runWith(Sink.head).flatMap { response => 
    context complete updateHeaders(httpCookie)(response) 
} 

純流量

你甚至可以完全避免使用路由傳遞一個FlowHttpExt#bindAndHandle

val myRoute : Flow[HttpRequest, HttpResponse, _] = 
    flow(server,port) map updateHeaders(httpCookie) 
+0

嗨,感謝您的幫助!在我的情況下,手動添加'Set-Cookie'頭並不是那麼容易,因爲我不想替換現有的'Set-Cookie'數據,而只是添加我的cookie(我也想保留所有頭文件)。不過,我用'RawHeader'手動執行它。 –

+0

@JohnDoe歡迎您。快樂黑客... –