在Lagom服务中,您可以向服务描述符添加HeaderFilter。在HeaderFilter中,通常用于处理协议协商或身份验证。
单个HeaderFilter可以实现这样的转换,请求离开客户端或进入服务器,响应离开服务器并进入客户端。下面是一个使用User-Agent头读取服务名称的示例:

  1. object UserAgentHeaderFilter extends HeaderFilter {
  2. override def transformClientRequest(request: RequestHeader): RequestHeader = {
  3. request.principal match {
  4. case Some(principal: ServicePrincipal) =>
  5. request.withHeader(HeaderNames.USER_AGENT, principal.serviceName)
  6. case _ => request
  7. }
  8. }
  9. override def transformServerRequest(request: RequestHeader): RequestHeader = {
  10. request.getHeader(HeaderNames.USER_AGENT) match {
  11. case Some(userAgent) =>
  12. request.withPrincipal(ServicePrincipal.forServiceNamed(userAgent))
  13. case _ =>
  14. request
  15. }
  16. }
  17. override def transformServerResponse(
  18. response: ResponseHeader,
  19. request: RequestHeader
  20. ): ResponseHeader = response
  21. override def transformClientResponse(
  22. response: ResponseHeader,
  23. request: RequestHeader
  24. ): ResponseHeader = response
  25. }

UserAgentHeaderFilter是默认的HeaderFilter,在未指定的情况下Lagom服务会默认使用此过滤器。它使用ServicePrincipal,用服务名称来标识客户机。
UserAgentHeaderFilter中,如果在请求中指定了ServicePrincipal,则在准备客户端调用添加用户代理消息头时,将调用transformClientRequest处的代码。请注意,默认情况下,Lagom在发出请求时会自动将当前服务名称作为ServicePrincipal传递。在服务器端,transformServerRequest将用于读取用户代理头,并将该值设置为请求的Principal
请记住,头过滤器只应用于处理横切协议方面的问题,仅此而已。例如,您可能有一个头过滤器,它描述了当前经过身份验证的用户如何通过HTTP协议进行通信(例如,通过添加用户头)。跨领域的问题,例如身份授权和验证,不应该在头过滤器中处理,而应该使用服务调用组合来处理。

消息头过滤器组合

每个服务描述符Descriptor 只能有一个HeaderFilter。为了同时使用多个过滤器,您可以使用HeaderFilter.composite组合它们,它将返回一个HeaderFilter,该HeaderFilter将链接您合成的所有HeaderFilter。在编写时,顺序很重要,因此在发送消息头时,组合的过滤器将按提供的顺序使用,而在接收消息头时,过滤器将按相反的顺序使用。因此,如果我们有以下过滤器:

  1. class VerboseFilter(name: String) extends HeaderFilter {
  2. private val log = LoggerFactory.getLogger(getClass)
  3. def transformClientRequest(request: RequestHeader) = {
  4. log.debug(name + " - transforming Client Request")
  5. request
  6. }
  7. def transformServerRequest(request: RequestHeader) = {
  8. log.debug(name + " - transforming Server Request")
  9. request
  10. }
  11. def transformServerResponse(response: ResponseHeader, request: RequestHeader) = {
  12. log.debug(name + " - transforming Server Response")
  13. response
  14. }
  15. def transformClientResponse(response: ResponseHeader, request: RequestHeader) = {
  16. log.debug(name + " - transforming Client Response")
  17. response
  18. }
  19. }

我们注册两个过滤器分别命名为 Fooand Bar:

  1. def descriptor = {
  2. import Service._
  3. named("hello")
  4. .withCalls(
  5. call(sayHello)
  6. )
  7. .withHeaderFilter(
  8. HeaderFilter.composite(
  9. new VerboseFilter("Foo"),
  10. new VerboseFilter("Bar")
  11. )
  12. )
  13. }

然后调用服务,我们将在服务器输出日志中获得以下信息:

  1. [debug] Bar - transforming Server Request
  2. [debug] Foo - transforming Server Request
  3. [debug] Foo - transforming Server Response
  4. [debug] Bar - transforming Server Response