如何在 Akka Scala 的 HttpResponse 中设置 `Set-Cookie` header?
How to set `Set-Cookie` header in HttpResponse in Akka Scala?
我的应用程序中有以下路线:
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)
}
}
我的问题是我不能使用 out-of-the-box setCookie
方法(或者我可以吗?)因为我在路线内,所以我会收到类型错误。我考虑过手动向 HttpResponse
添加一个 header 元素(在上面的示例中 r
),但这很麻烦。
知道如何轻松添加 Set-Cookie
header 元素吗?
setCookie 指令
A Route
就是 a type definition: (RequestContext) => Future[RouteResult]
。因此,您可以使用函数组合将 cookie 添加到来自下游服务的 HttpResponse
。
首先创建一个使用预定义流的转发器:
val forwardRequest : HttpRequest => Future[HttpResponse] =
Source
.single(_)
.via(flow(server, port))
.runWith(Sink.head)
然后用 getRequest
和一个从 HttpResponse
到 RouteResult
的转换器组成该函数:
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)
}
纯流量
您甚至可以通过将 Flow
传递给 HttpExt#bindAndHandle
来完全避免使用路由:
val myRoute : Flow[HttpRequest, HttpResponse, _] =
flow(server,port) map updateHeaders(httpCookie)
我的应用程序中有以下路线:
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)
}
}
我的问题是我不能使用 out-of-the-box setCookie
方法(或者我可以吗?)因为我在路线内,所以我会收到类型错误。我考虑过手动向 HttpResponse
添加一个 header 元素(在上面的示例中 r
),但这很麻烦。
知道如何轻松添加 Set-Cookie
header 元素吗?
setCookie 指令
A Route
就是 a type definition: (RequestContext) => Future[RouteResult]
。因此,您可以使用函数组合将 cookie 添加到来自下游服务的 HttpResponse
。
首先创建一个使用预定义流的转发器:
val forwardRequest : HttpRequest => Future[HttpResponse] =
Source
.single(_)
.via(flow(server, port))
.runWith(Sink.head)
然后用 getRequest
和一个从 HttpResponse
到 RouteResult
的转换器组成该函数:
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)
}
纯流量
您甚至可以通过将 Flow
传递给 HttpExt#bindAndHandle
来完全避免使用路由:
val myRoute : Flow[HttpRequest, HttpResponse, _] =
flow(server,port) map updateHeaders(httpCookie)