在Lagom服务中,您可以向服务描述符添加HeaderFilter
。在HeaderFilter
中,通常用于处理协议协商或身份验证。
单个HeaderFilter
可以实现这样的转换,请求离开客户端或进入服务器,响应离开服务器并进入客户端。下面是一个使用User-Agent
头读取服务名称的示例:
object UserAgentHeaderFilter extends HeaderFilter {
override def transformClientRequest(request: RequestHeader): RequestHeader = {
request.principal match {
case Some(principal: ServicePrincipal) =>
request.withHeader(HeaderNames.USER_AGENT, principal.serviceName)
case _ => request
}
}
override def transformServerRequest(request: RequestHeader): RequestHeader = {
request.getHeader(HeaderNames.USER_AGENT) match {
case Some(userAgent) =>
request.withPrincipal(ServicePrincipal.forServiceNamed(userAgent))
case _ =>
request
}
}
override def transformServerResponse(
response: ResponseHeader,
request: RequestHeader
): ResponseHeader = response
override def transformClientResponse(
response: ResponseHeader,
request: RequestHeader
): ResponseHeader = response
}
此UserAgentHeaderFilter是默认的HeaderFilter,在未指定的情况下Lagom服务会默认使用此过滤器。它使用ServicePrincipal,用服务名称来标识客户机。
在UserAgentHeaderFilter
中,如果在请求中指定了ServicePrincipal,则在准备客户端调用添加用户代理消息头时,将调用transformClientRequest
处的代码。请注意,默认情况下,Lagom在发出请求时会自动将当前服务名称作为ServicePrincipal传递。在服务器端,transformServerRequest
将用于读取用户代理头,并将该值设置为请求的Principal。
请记住,头过滤器只应用于处理横切协议方面的问题,仅此而已。例如,您可能有一个头过滤器,它描述了当前经过身份验证的用户如何通过HTTP协议进行通信(例如,通过添加用户头)。跨领域的问题,例如身份授权和验证,不应该在头过滤器中处理,而应该使用服务调用组合来处理。
消息头过滤器组合
每个服务描述符Descriptor
只能有一个HeaderFilter
。为了同时使用多个过滤器,您可以使用HeaderFilter.composite
组合它们,它将返回一个HeaderFilter,该HeaderFilter将链接您合成的所有HeaderFilter
。在编写时,顺序很重要,因此在发送消息头时,组合的过滤器将按提供的顺序使用,而在接收消息头时,过滤器将按相反的顺序使用。因此,如果我们有以下过滤器:
class VerboseFilter(name: String) extends HeaderFilter {
private val log = LoggerFactory.getLogger(getClass)
def transformClientRequest(request: RequestHeader) = {
log.debug(name + " - transforming Client Request")
request
}
def transformServerRequest(request: RequestHeader) = {
log.debug(name + " - transforming Server Request")
request
}
def transformServerResponse(response: ResponseHeader, request: RequestHeader) = {
log.debug(name + " - transforming Server Response")
response
}
def transformClientResponse(response: ResponseHeader, request: RequestHeader) = {
log.debug(name + " - transforming Client Response")
response
}
}
我们注册两个过滤器分别命名为 Foo
and Bar
:
def descriptor = {
import Service._
named("hello")
.withCalls(
call(sayHello)
)
.withHeaderFilter(
HeaderFilter.composite(
new VerboseFilter("Foo"),
new VerboseFilter("Bar")
)
)
}
然后调用服务,我们将在服务器输出日志中获得以下信息:
[debug] Bar - transforming Server Request
[debug] Foo - transforming Server Request
[debug] Foo - transforming Server Response
[debug] Bar - transforming Server Response