在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 = responseoverride 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}}
我们注册两个过滤器分别命名为 Fooand 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
