Heroku 404上的Scala Jetty Webapp

时间:2019-03-24 19:04:40

标签: scala heroku jetty udash

我正在使用Scala Web框架(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的配置/特征?

编辑

试图应用建议的更改并最终得到以下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 :(得分:0)

一些需要调整的东西可能会对您有所帮助。

  1. resourceBase作为DefaultServlet上的初始参数用于alternate static file serving
  2. 改为使用ServletContextHandler.setBaseResource(Resource)
  3. 使用Resource.newResource(String)创建新的资源引用。这应该是文件系统上的绝对路径,或者是绝对URI引用。没有相对路径或URI片段。
  4. DefaultServlet必须位于url-pattern的{​​{1}}上,而不是"/"(这是Servlet规范要求)
  5. "/*"必须被命名,并且必须具有名称DefaultServlet(这是servlet规范的要求,例如,请参见第1点的链接)
  6. "default"设置为明确要使用的基本上下文路径。

一些观察:

您的示例代码将仅提供ServletContextHandler.setContextPath("/")中的静态内容。

由于您没有配置resourceBase,因此默认情况下它将投放welcomeFiles(如果您未指定要访问的特定静态资源)

您有一个<resourceBase>/index.html设置(SessionListener),但是由于没有任何东西可以访问org.atmosphere.cpr.SessionSupport,因此该代码几乎是无操作的。

示例代码库中没有来自自定义Servlet或Filter的动态结果。