惯例并不总是很好。 我最近在Codurance开始了一个新的内部Web项目,我决定使用Scala。 因为我不喜欢大型框架,所以选择Scalatra作为微型Web框架。
第一个挑战是我想用不同的目录结构来组织我的应用程序。 默认情况下, sbt和Scalatra使用与maven相同的约定:
> /src/main/scala // source code
> /src/main/resources // production resources
> /scr/test/scala // tests
> /scr/test/resouces // test resources
在过去的几年中,我一直在为项目尝试不同的目录结构。 在解释业务领域时,我希望我的目录更加有意义。 新的目录结构是我所谓的交互驱动设计(IDD)的一部分 ,有关其完整说明,请参见我们的视频区域 。 在该演讲中,我将详细介绍新目录结构背后的原理。
我想用于这个新项目的目录结构是:
> /src/core/scala // source code for my core domain
> /src/core-test/scala // tests for my core domain
> /src/data/resources // resources for data migration and test data
> /src/data/scala // code for data migration and test data
> /src/web/resources // delivery mechanism resources
> /src/web/scala // delivery mechanism code (controllers, API, etc)
> /src/web/webapp // web files (WEB-INF folder, css, javascript, Jade templates, etc)
> /src/web-test/scala // tests for my delivery mechanism
同样,如果您观看“ 交互驱动设计”(IDD)演讲 ,则上面的目录结构将更有意义。
最大的挑战是将默认目录main重命名为web 。 那破坏了整个世界。 这是我必须修复的所有更改:
build.sbt
unmanagedSourceDirectories in Compile := Seq((baseDirectory.value / "src/core/scala"),
(baseDirectory.value / "src/data/scala"),
(baseDirectory.value / "src/web/scala"))
unmanagedResourceDirectories in Compile += baseDirectory.value / "src/data/resources"
unmanagedSourceDirectories in Test := Seq((baseDirectory.value / "src/core-test/scala"),
(baseDirectory.value / "src/web-test/scala"))
webappSrc in webapp <<= (baseDirectory in Compile) map { _ / "src/web/webapp" }
webappDest in webapp <<= (baseDirectory in Compile) map { _ / "src/web/webapp" }
最后两行需要用到webappSrc和webappDest ,因为我还使用了一个手动启动Jetty的类,该类将Scalatra侦听器钩住。
码头工人
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.servlet.DefaultServlet
import org.eclipse.jetty.webapp.WebAppContext
import org.scalatra.servlet.ScalatraListener
object JettyLauncher {
def main(args: Array[String]) {
val port = if(System.getenv("PORT") != null) System.getenv("PORT").toInt else 8089
val server = new Server(port)
val context = new WebAppContext()
context.setClassLoader(JettyLauncher.getClass.getClassLoader)
context setContextPath "/"
context.setResourceBase("src/web/webapp")
context.addEventListener(new ScalatraListener)
context.addServlet(classOf[DefaultServlet], "/")
server.setHandler(context)
server.start
server.join
}
}
执行此类时,找不到ScalatraBootstrap ,这就是为什么我必须在JettyLauncher中添加以下行:
> context.setClassLoader(JettyLauncher.getClass.getClassLoader)
Scalatra依靠默认目录main来找到ScalatraBootstrap ,这就是我设法确保可以找到ScalatraBootstrap的方式。
请注意,我还必须更改资源库,指向Web文件夹而不是main :
> context.setResourceBase("src/web/webapp")
因为我用玉通过模板Scalate的 ,我不得不改变对build.scala Scalate的模板配置。
build.scala
object MonitorBuild extends Build {
val Organization = "com.codurance"
val Name = "monitor"
val Version = "0.1.0-SNAPSHOT"
val ScalaVersion = "2.11.6"
val ScalatraVersion = "2.4.0.RC1"
lazy val project = Project(
"monitor",
file("."),
settings = ScalatraPlugin.scalatraSettings ++ scalateSettings ++ Seq(
// dependencies and some other stuff here
scalateTemplateConfig in Compile <<= (sourceDirectory in Compile) { base =>
Seq(
TemplateConfig(
new RichFile(new File("src")) / "web" / "webapp" / "WEB-INF" / "templates",
Seq.empty,
Seq(
Binding("context", "_root_.org.scalatra.scalate.ScalatraRenderContext", importMembers = true, isImplicit = true)
),
Some("templates")
)
)
}
)
)
}
上面重要的一行是:
> new RichFile(new File("src")) / "web" / "webapp" / "WEB-INF" / "templates"
这使Scalate在Web目录中而不是main中找到模板。
确保在plugins.sbt中有这些行
> addSbtPlugin("com.mojolly.scalate" % "xsbt-scalate-generator" % "0.5.0")
>
> addSbtPlugin("org.scalatra.sbt" % "scalatra-sbt" % "0.4.0")
我不需要在web.xml和ScalatraBootstrap上进行任何更改。
上述配置使我可以通过以下方式运行应用程序
> ./sbt container:start
这就是我通常在本地运行应用程序的方式,还允许我创建一个胖jar文件并执行JettyLauncher类,这就是我在生产环境中运行的方式:
> java -cp <myapplication>.jar com.codurance.JettyLauncher
胖子jar文件是通过以下方式创建的:
> ./sbt assembly
这是IntelliJ IDEA上折叠目录结构的外观:
这是展开后的样子:
尽管花了我一段时间才能弄清所有这些,但我很高兴能够以对我们有意义的方式来组织我的项目。
翻译自: https://www.javacodegeeks.com/2015/11/changing-scalatra-sbt-default-directories.html
本文分享了在使用Scala和Scalatra框架开发Web项目时,如何调整默认目录结构以实现更符合业务需求的交互驱动设计(IDD)。作者详细介绍了修改sbt配置、Jetty启动类及模板配置的过程。



1058

被折叠的 条评论
为什么被折叠?



