[英]How to set `Set-Cookie` header in HttpResponse in Akka Scala?
I have the following route in my app: 我的应用中有以下路线:
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)
}
}
My problem is that I can't use the out-of-the-box setCookie
method (or can I?) because I am inside a route, so I will get a type error. 我的问题是我不能使用现成的
setCookie
方法(或者可以吗?),因为我在路由内,所以会出现类型错误。 I thought about manually adding a header element to the HttpResponse
(in the example above r
), but that is quite cumbersome. 我考虑过手动将标头元素添加到
HttpResponse
(在r
上面的示例中),但这很麻烦。
Any ideas how I can easily add the Set-Cookie
header element? 有什么想法可以轻松添加
Set-Cookie
标头元素吗?
setCookie Directive setCookie指令
A Route
is just a type definition : (RequestContext) => Future[RouteResult]
. Route
只是类型定义 : (RequestContext) => Future[RouteResult]
。 Therefore you can use function composition to add a cookie to the HttpResponse
coming from the downstream service. 因此,您可以使用函数组合将cookie添加到来自下游服务的
HttpResponse
。
First create a forwarder that utilizes the predefined flow: 首先创建一个使用预定义流程的转发器:
val forwardRequest : HttpRequest => Future[HttpResponse] =
Source
.single(_)
.via(flow(server, port))
.runWith(Sink.head)
Then compose that function with getRequest
and a converter from HttpResponse
to RouteResult
: 然后使用
getRequest
和从HttpResponse
到RouteResult
的转换器组成该函数:
val queryExternalService : Route =
getRequest andThen forwardRequest andThen (_ map RouteResult.Complete)
Finally, set the cookie: 最后,设置cookie:
val httpCookie : HttpCookie = ??? //not specified in question
val myRoute : Route = setCookie(httpCookie)(queryExternalService)
Manual Addendum in Route 路线中的手册附录
You can manually set the cookie: 您可以手动设置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)
}
Pure Flow 纯流量
You can even avoid using Routes altogether by passing a Flow
to HttpExt#bindAndHandle
: 您甚至可以通过将
Flow
传递给HttpExt#bindAndHandle
来完全避免使用Routes:
val myRoute : Flow[HttpRequest, HttpResponse, _] =
flow(server,port) map updateHeaders(httpCookie)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.