2017-05-10 23 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欢迎您。快乐黑客... –