我正在测试Scala Web框架(Udash)并试图在Heroku中运行一个玩具示例。我按照Heroku文档中的说明在本地运行没有问题:
sbt compile stage
heroku local web
但是,部署后,我输入的任何网址都会转到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
在本地运行应用程序时,我会正确进入登录页面。
谢谢!谢谢!
一些可以调整的东西可能会对你有所帮助。
resourceBase
作为DefaultServlet
的初始参数是alternate static file serving。ServletContextHandler.setBaseResource(Resource)
。Resource.newResource(String)
创建新的资源引用。这应该是文件系统上的绝对路径,或绝对URI引用。没有相对路径或URI片段。DefaultServlet
必须在url-pattern
的"/"
,而不是"/*"
(这是servlet规范要求)DefaultServlet
,并且必须具有名称"default"
(这是servlet规范要求,例如,请参阅第1点的链接)ServletContextHandler.setContextPath("/")
以明确您要使用的基本上下文路径。一些观察:
您的示例代码仅提供resourceBase
之外的静态内容。
由于您没有配置welcomeFiles
,默认情况下它将提供<resourceBase>/index.html
(如果您没有指定要访问的特定静态资源)
你有一个SessionListener
设置(org.atmosphere.cpr.SessionSupport
),但由于没有什么可以访问Session
,该代码几乎是一个无操作。
示例代码库中存在自定义Servlet或Filter的动态结果。