搭建Lift项目
sbt -> sbt + jetty -> sbt + jetty + lift
本章的示例代码在:http://git.oschina.net/yangbajing/lift-book/tree/master/examples/lift-blank
安装Sbt
详细内容请读附录A. 使用Sbt
创建sbt工程
现在我们重头开始建立一个lift项目,首先需要创建一个sbt工程。我们建立工程目录在:/data/lift-book/examples/lift-blank
,并建立目录结构如下:
.
├── 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
等文件吧。
下载sbt
进行 lift-blank
工程目录:
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
:
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的插件配置文件。
首先来看看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
。
其它配置文件请看源码,注释有较详细的说明。
导入Lift支持
在本节,你将学会添加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实战之旅……
简单的说说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
- Lift解析index.html
- 找到
class="lift:helloWorld.howdy
,根据helloWorld.howdy
找到相应类的相应方法就是:code.snippet.HelloWorld.howdy
- 找到
data-lift="HelloWorld",根据
HelloWorld找到相应类的相应方法就是:
code.snippet.HelloWorld.render` - Lift从
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
来源:oschina
链接:https://my.oschina.net/u/124262/blog/107693