sbt -> sbt + jetty -> sbt + jetty + lifthtml
本章的示例代码在:http://git.oschina.net/yangbajing/lift-book/tree/master/examples/lift-blankjava
详细内容请读附录A. 使用Sbtgit
如今咱们重头开始创建一个lift项目,首先须要建立一个sbt工程。咱们创建工程目录在:/data/lift-book/examples/lift-blank
,并创建目录结构以下:github
. ├── project │ ├── Build.scala │ ├── BuildSettings.scala │ ├── Dependencies.scala │ └── plugins.sbt ├── sbt ├── sbt-launch-0.13.0.jar ├── sbt.bat └── src ├── main │ ├── scala │ │ ├── bootstrap │ │ │ └── liftweb │ │ │ └── Boot.scala │ │ └── code │ │ ├── comet/ │ │ ├── helper/ │ │ ├── model/ │ │ └── snippet/ │ └── webapp │ └── WEB-INF │ └── web.xml └── test └── scala/
以后章节咱们将基于此项目进行功能扩展。让咱们先来实习那些 .scala
,.sbt
,.xml
等文件吧。web
进行 lift-blank
工程目录:shell
wget -c http://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.13.0/sbt-launch.jar mv sbt-launch.jar sbt-launch-0.13.0.jar
建立sbt
启动脚本,并为其添加可执行权限chmod +x sbt
:apache
SBT_OPTS="-Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M" java $SBT_OPTS -jar `dirname $0`/sbt-launch-0.13.0.jar "$@"
sbt有两种配置文件形式,咱们采用.scala
配置文件形式。如今project
目录中分别建立:BuildSettings.scala
,Build.scala
,Dependencies.scala
,plugins.sbt
文件。咱们在BuildSettings.scala
文件中保存一些全局配置荐、Build.scala
文件是实际的配置功能文件、Dependencies.scala
将保存全部的依赖jar包、plugins.sbt
是sbt的插件配置文件。bootstrap
首先来看看Build.scala
文件内容:浏览器
object Build extends Build { import BuildSettings._ import Dependencies._ override lazy val settings = super.settings :+ { shellPrompt := (s => Project.extract(s).currentProject.id + " > " ) }
这里配置在sbt终端显示的前导符号。服务器
lazy val blank = webProject("blank", file("."), 48080) .settings( description := "Liftweb-blank")
这里设置项目名称为blank
,目录为当前路径,Web服务端口为48080。
private def webProject(id: String, base: File, iPort: Int): Project = { import com.earldouglas.xsbtwebplugin.{WebPlugin, PluginKeys} myProject(id, base) .settings(WebPlugin.webSettings: _*) .settings( PluginKeys.port in WebPlugin.container.Configuration := iPort, libraryDependencies ++= (container(_servlet30) ++ container(_jetty) ++ compile(_liftweb))) } private def myProject(id: String, base: File): Project = Project(id, base) .settings(basicSettings: _*) .settings( resolvers ++= Seq( "releases" at "http://oss.sonatype.org/content/repositories/releases", "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/", "snapshots" at "http://oss.sonatype.org/content/repositories/snapshots", "Typesafe Snapshots" at "http://repo.typesafe.com/typesafe/snapshots/"), libraryDependencies ++= ( test(_scalatest))) }
webProject
和myProject
是两个帮助函数,用以方便配置web项目和sbt项目。以后章节对此会有详细说明。如今须要知道的是若你只是想建立一个sbt
项目,那使用myProject
。若建立的是一个web
项目,就必需得使用webProject
。
其它配置文件请看源码,注释有较详细的说明。
在本节,你将学会添加Jetty以使sbt项目支持Web开发。还将学会在在scala里写Servlet并添加Lift支持
要使用sbt工程支持web开发,须要为sbt配置一个插件:xsbtwebplugin
,官方网站在:xsbt-web-plugin。为sbt配置此插件很是简单,首先在project/plugins.sbt
文件中为其指定插件下载位置:
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "0.4.2")
(注:在.sbt
配置文件中,每一个配置项<就是每一行>之间必需用空行分隔。)
回头咱们在看project/Build.scala
配置文件中的webProject
帮助函数:
private def webProject(id: String, base: File, iPort: Int): Project = { import com.earldouglas.xsbtwebplugin.{WebPlugin, PluginKeys} myProject(id, base) .settings(WebPlugin.webSettings: _*) .settings( PluginKeys.port in WebPlugin.container.Configuration := iPort, libraryDependencies ++= (container(_servlet30) ++ container(_jetty) ++ compile(_liftweb))) }
能够看到,.settings(WebPlugin.webSettings: _*)
一行导入了xsbt-web-plugin配置。PluginKeys.port
指定web服务器的运行端口号。而libraryDependencies
添加了jar包依赖,分别是:servlet、jetty和liftweb。如今一个支持Liftweb开发的sbt工程就配置完成,接下来咱们将进入lift实战之旅……
完整代码在examples/lift-blank/src/main/webapp/WEB-INF/web.xml
Lift程序不须要一大堆的xml或XXX文件来进行配置,它只要在web.xml中写上一个Filter就行:
<filter> <filter-name>LiftFilter</filter-name> <filter-class>net.liftweb.http.LiftFilter</filter-class> </filter> <filter-mapping> <filter-name>LiftFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
固然,也不是说Lift就不能定置了。它也是能够定制的,并且定制选项很是的丰富。Lift全部的环境定制均可以放到 bootstrap.liftweb.Boot
类中进行。咱们在 Boot.boot()
方法中配置咱们的Lift应用环境。(注:关于配置内容,请看代码)
对于任何Web程序来讲,咱们都须要从浏览器(或其它的什么东西)访问它。这里,就涉及到一个页面路径分发的问题! Lift是View First(视图优先)的框架,它不一样于通常的MVC模型。Lift没有控制器,用户访问的URI是什么,它就返回什么!好比说 用户访问: http://localhost:8081/first/index
这个路径,Lift就会访问磁盘上实际的 /first/index.html(或者.htm)文件。不像Servlet,你须要配置一个<servlet-mapping>去进行地址映射。这就是View First,一句话:你访问的URI就是视图,不是控制器!
(注:Lift也支持URI Rewrite和Rest API机制,并且实现是那么的简洁,一致和强大!后面的部分会讲到。)
对于咱们的第一个程序,你能够在sbt console中使用 container:start
命令启动 jetty。
$ ./sbt [info] Loading project definition from /data/workspace/lift-book/examples/lift-blank/project [info] Set current project to blank (in build file:/data/workspace/lift-book/examples/lift-blank/) blank > container:start [warn] o.e.j.w.WebAppContext@11ae80fa{/,null,null} contextPath ends with / [warn] Empty contextPath [info] jetty-9.0.5.v20130815 [info] NO JSP Support for /, did not find org.apache.jasper.servlet.JspServlet SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. [info] Started o.e.j.w.WebAppContext@11ae80fa{/,[file:/data/workspace/lift-book/examples/lift-blank/src/main/webapp/],AVAILABLE} [info] Started NetworkTrafficSelectChannelConnector@153a859b{HTTP/1.1}{0.0.0.0:48080} [success] Total time: 2 s, completed 2013-9-5 0:55:52 blank >
如今让咱们访问 http://localhost:48080/
瞧瞧,你会看到输出了当前时间和一段话。接下来,让我给你娓娓道来 这些是怎样呈现的。
http://localhost:48080/index
class="lift:helloWorld.howdy
,根据 helloWorld.howdy
找到相应类的相应方法就是: code.snippet.HelloWorld.howdy
data-lift="HelloWorld",根据
HelloWorld找到相应类的相应方法就是:
code.snippet.HelloWorld.render`class="lift:surround?with=default;at=content"
打开 templates-hidden/default.html
模板。 with=default
指定把寻找哪一个模板, at=content
设置将当前内容插入到模板的 id=content
片断中。下面咱们来简单的说说 Lift
的 snippet
机制。Snippet,就是“片断”。Lift把Web页面分红一个一个的片断,就像传统的 GUI 开发同样一个窗口上面由不少的控件组成。而这个Snippet能够很大,它里面包含了table, input, textarea等html标签;也能够很小,只是输出一句话!
下载整个完整的lift-book
,定位到examples/lift-blank
目录。执行如下命令:
./sbt