자바 개발자가 https://www.playframework.com/documentation/2.6.x/ScalaHttpFilters를 보면서 스칼라 Play 애플리케이션을 만들 때 조금 헤맬 수 있다.
아래와 같은 코드가 있다고 가정하자. 특별히 소스를 분석하지 않아도 적당히 문서를 읽으면서 알수도 있지만,,
head first로 개념을 이해할 수 있다.
Filters
package filters
import javax.inject.Inject
import play.api.http.{DefaultHttpFilters, EnabledFilters}
import play.filters.gzip.GzipFilter
class Filters @Inject() (
defaultFilters: EnabledFilters,
gzip: GzipFilter,
logging: LoggingFilter
) extends DefaultHttpFilters (defaultFilters.filters :+ gzip :+ logging: _*)
LoggingFilter
package filters
import javax.inject.Inject
import akka.stream.Materializer
import play.api.Logger
import play.api.mvc._
import scala.concurrent.{ExecutionContext, Future}
class LoggingFilter @Inject() (implicit val mat: Materializer, ec: ExecutionContext) extends Filter {
def apply(nextFilter: RequestHeader => Future[Result])
(requestHeader: RequestHeader): Future[Result] = {
val startTime = System.currentTimeMillis
nextFilter(requestHeader).map { result =>
val endTime = System.currentTimeMillis
val requestTime = endTime - startTime
val log = s"${requestHeader.method} ${requestHeader.uri} took ${requestTime}ms and returned ${result.header.status}"
if (requestTime > 3000) {
Logger.warn(log)
} else {
Logger.debug(log)
}
result
}
}
}
또는 아래와 같이 사용한다.
play.filters.enabled += filters.LoggingFilter
만약 play.filters.enabled를 사용하지 않으면.. 아래와 같이 써야 한다.
play.http.filters = filters.Filters
아래와 같이 사용하면 다음 에러가 발생한다.
play.http.filters += filters.LoggingFilter
Configuration error: Configuration error[reference.conf @ jar:file:/Users/samuel.kim/.ivy2/cache/com.typesafe.play/play_2.12/jars/play_2.12-2.6.6.jar!/reference.conf: 69: Cannot concatenate object or list with a non-object-or-list, ConfigNull(null) and SimpleConfigList(["filters.Filters"]) are not compatible]
아래와 같이 사용하면 에러가 발생한다.
play.filters.enabled += filters.Filters
클래스를 보면 Filters의 첫 번째 매개변수인 EnabledFilters의 내부를 보면.. 필터를 구성하는 개념이다.
private val enabledKey = "play.filters.enabled"
private val disabledKey = "play.filters.disabled"
즉 Filters는 상위 개념인데, 처음에는 None으로 지정되어 있다. 따러서 ConfigNull이 이미 들어가 있다. 따라서 Null에 List를 추가하면 당연히 에러가 발생할 것이다. play.http.filters는 애플리케이션에서 지정하는 filter 목록을 정의하는 것이라 할 수 있겠다.
play.http.filters += filters.Filters
play.http.filters = filters.MyFilters
extends DefaultHttpFilters(defaultFilters.filters :+ gzip :+ logging: _*)
class DefaultHttpFilters @Inject() (val filters: EssentialFilter*)
defaultFilters.filters :+ gzip :+ logging)
이를 : _*) 를 추가하면 EssentailFilter* 타입이 된다.
자바에서는 varargs인데.
스칼라에서는 : _*으로 사용하면 컴파일러에게 seq/array를 varargs로 변환하라는 신호이다.
scala> def foo(args: Int*) = args.map{_ + 1}
foo: (args: Int*)Seq[Int]
scala> foo(-1, 0, 1)
res0: Seq[Int] = ArrayBuffer(0, 1, 2)
'scala' 카테고리의 다른 글
[play] JWT token 예제 (0) | 2018.02.09 |
---|---|
play 2.6 새로운 기능 (0) | 2018.02.08 |
[play framework] WSClient 바로 사용하기 (0) | 2018.02.07 |
trait의 내부 필드 접근하기 - 컴패년 오브젝트 (0) | 2018.02.02 |
[scala] sksamuel 라이브러리에서 동기 코드로 개발 (await.result) 예제 (0) | 2018.01.30 |