Веб-приложение Scala Jetty на Heroku 404 - PullRequest
0 голосов
/ 24 марта 2019

Я тестирую с помощью веб-фреймворка Scala (Udash) и пытаюсь запустить игрушечный пример в Heroku. У меня он работает без проблем на местном уровне, следуя инструкциям в документации Heroku:

sbt compile stage
heroku local web

Однако после развертывания любой URL, который я набираю, переходит на 404, даже на целевую страницу приложения. Это объекты, которые я использую:

object Launcher extends CrossLogging {
  def main(args: Array[String]): Unit = {
    val port = Properties.envOrElse("PORT", "5000").toInt
    val server = new ApplicationServer(port, "frontend/target/UdashStatics/WebContent")
    server.start()
    logger.info(s"Application started...")
  }
}

class ApplicationServer(val port: Int, resourceBase: String) {
  private val server = new Server(port)
  private val contextHandler = new ServletContextHandler
  private val appHolder = createAppHolder()

  contextHandler.setSessionHandler(new SessionHandler)
  contextHandler.setGzipHandler(new GzipHandler)
  contextHandler.getSessionHandler.addEventListener(new org.atmosphere.cpr.SessionSupport())
  contextHandler.addServlet(appHolder, "/*")
  server.setHandler(contextHandler)

  def start(): Unit = server.start()
  def stop(): Unit = server.stop()

  private def createAppHolder() = {
    val appHolder = new ServletHolder(new DefaultServlet)
    appHolder.setAsyncSupported(true)
    appHolder.setInitParameter("resourceBase", resourceBase)
    appHolder
  }
}

Есть ли какие-либо конфигурации / характеристики Heroku, которые мне не хватает?

EDIT

Пытался применить предложенные изменения и в итоге получил следующий ApplicationContext:

class ApplicationServer(val port: Int, val resourceBase: String) {
  val server = new Server()
  val connector = new ServerConnector(server)
  connector.setPort(port)
  server.addConnector(connector)
  private val appHolder = createAppHolder()

  val context = new ServletContextHandler(ServletContextHandler.SESSIONS)

  context.setBaseResource(Resource.newResource(resourceBase))
  context.setContextPath("/")
  context.addServlet(appHolder, "/")
  server.setHandler(context)

  private def createAppHolder() = {
    val appHolder = new ServletHolder("default", classOf[DefaultServlet])
    appHolder.setInitParameter("dirAllowed", "true")
    appHolder.setInitParameter("resourceBase", resourceBase)
    appHolder
  }

  def start(): Unit = server.start()
  def stop(): Unit = server.stop()
}

Однако после развертывания на Heroku я все еще получаю сообщение об ошибке 404 даже на целевой странице:

HTTP ERROR 404
Problem accessing /. Reason:
    Not Found

При запуске приложения на локальном компьютере я правильно попадаю на целевую страницу.

Спасибо! Спасибо!

1 Ответ

0 голосов
/ 25 марта 2019

Несколько вещей для настройки, которые могут вам помочь.

  1. resourceBase в качестве параметра init для DefaultServlet предназначен для альтернативного статического файла, обслуживающего .
  2. Вместо этого используйте ServletContextHandler.setBaseResource(Resource).
  3. Используйте Resource.newResource(String) для создания новой ссылки на ресурс. Это должен быть абсолютный путь в файловой системе или абсолютная ссылка на URI. нет относительных путей или фрагментов URI.
  4. DefaultServlet должен быть url-pattern из "/", а не "/*" (это требование спецификации сервлета)
  5. DefaultServlet должно иметь имя и имя "default" (это требование спецификации сервлета, см. Ссылку на пункт 1, например)
  6. установить ServletContextHandler.setContextPath("/") в явном виде о том, какой базовый контекстный путь вы хотите использовать.

Некоторые наблюдения:

Ваш пример кода будет обслуживать только статический контент из resourceBase.

Поскольку у вас не настроен welcomeFiles, он будет обслуживать <resourceBase>/index.html по умолчанию (если вы не укажете определенный статический ресурс, к которому хотите получить доступ)

У вас есть SessionListener setup (org.atmosphere.cpr.SessionSupport), но, поскольку нет ничего, что могло бы получить доступ к Session, этот код в значительной степени не используется.

Там нет динамических результатов от пользовательских сервлетов или фильтров, присутствующих в вашем примере кода базы.

...