Как обслуживать статические ресурсы из файловой системы, а не JAR-комплект активов по умолчанию (Play Framework) - PullRequest
1 голос
/ 14 марта 2019

Play Framework связывает статические активы в пакет JAR, который используется во время выполнения для разрешения (посредством поиска по пути к классам) запрошенных активов.Вместо этого я хотел бы указать расположение файловой системы, откуда должны обслуживаться эти статические ресурсы.Я нашел хакерский способ сделать это (см. Ниже), но кажется, что должен быть более простой / лучший способ сделать это (хотя в документации это не упоминается).

Я знаю, что могу создать простой контроллер и "вручную" обслуживать ресурсы, но это не использует встроенные возможности кэширования и управления версиями, предоставляемые стандартным механизмом Assets.

(мое дополнительное требование заключается в том, что я хочу, чтобы некоторые активы были приватными, то есть требовать аутентификации / авторизации для доступа к ним)

Итак, вот мое текущее хакерское решение:

import java.net.URL
import java.nio.file.{Files, Paths}

import controllers._
import javax.inject.Inject
import play.api.http.{FileMimeTypes, HttpErrorHandler}
import play.api.mvc.{Action, AnyContent, ControllerComponents}
import play.api.{Configuration, Environment}

import scala.concurrent.ExecutionContext

object AssetResolver {
  def resolve(path: String): Option[URL] = {
    val resPath = Paths.get(path)
    if (Files.exists(resPath))
      Some(resPath.toUri.toURL)
    else None
  }
}

class AssetsController @Inject()(config: Configuration,
                                 env: Environment,
                                 httpErrorHandler: HttpErrorHandler,
                                 fileMimeTypes: FileMimeTypes)
                                (implicit ec: ExecutionContext) {
  private val configuration = AssetsConfiguration.fromConfiguration(config, env.mode)
  private val assetsMetadata = new DefaultAssetsMetadata(configuration, AssetResolver.resolve _, fileMimeTypes)
  private val assets = new Assets(httpErrorHandler, assetsMetadata)

  // authentication checking logic removed since irrelevant to question
  def secureAt(file: String): Action[AnyContent] = assets.at(file)
}

Тогда в conf/application.conf можно определить:

play.assets {
    path = "/absolute/path/to/assets"   # *must* be an absolute path
    urlPrefix = "/assets"
}

, а затем в conf/routes контроллер можно использовать следующим образом:

GET /assets/*file   controllers.AssetsController.secureAt(file)

Есть ли лучший способсделать это?(Я использую Play 2.7)

...