http://www.jdon.com/idea/play/install.html
Play 是一个开源高性能Web框架,能够基于Java或Scala编写可扩展可伸缩的应用系统,它能自动刷新源码的变动从而具有快速开发产品的能力,它还是一个无态非堵塞的框架,易于横向扩展。
Play!框架有如下特点:
- 高开发效率:Java EE和Spring框架并不适合快速原型开发,Play框架参考动态语言的快速开发能力,它支持热重载所有的Java代码和模板等,让你更快地迭代。基于Netty构建非堵塞异步机制。
- REST JSON 支持:非常容易编写RESTful应用,非常适合支持HTTP路由。
本教程将向您展示这两个特点。
安装
首先确认安装了Java环境,下载最新版本Play binary package ,注意不是Typesafe Activator。
将解压后的Play目录加入环境,windows是在环境设置中,如同Java一样加入path,Linux是:
export PATH=$PATH:/relativePath/to/play
检查是否正常安装:
play help
出现如下界面表示正常:
创建一个新的应用
在命令行输入,将提示你应用名称,然后选择创建Scala还是Java应用程序。
$ play new myFirstApp
通过下面命令启动自己的应用:
$ cd myFirstApp $ play 当出现[myFirstApp] $ 表示已经进入play控制台。
标准PLAY项目结构
app → 应用源码
└ assets → 编译后的 asset资源源码
└ stylesheets →CSS sources
└ javascripts → CoffeeScript sources
└ controllers → 应用控制器
└ models → 应用业务层
└ views → Templates模板
conf → 配置其他非编译资源(on classpath)
└ application.conf → 主配置文件
└ routes → 路由定义
public → 公共资源assets
└ stylesheets → CSS files
└ javascripts → Javascript files
└ images → Image files
project → sbt 配置文件
└ build.properties → Marker for sbt project
└ Build.scala → Application build script
└ plugins.sbt → sbt plugins
lib → 未管理的库包依赖
logs → Standard logs folder日志
└ application.log → Default log file
target → Generated 编译产生的文件
└ scala-2.10.0
└ cache
└ classes → Compiled class files
└ classes_managed → Managed class files (templates, ...)
└ resource_managed → Managed resources (less, ...)
└ src_managed → Generated sources (templates, ...)
test → source folder for unit or functional tests
play控制台
前面已经进入我的第一个应用控制台,键入
$ help play
获得帮助,运行命令如下:
$ run
在这种模式下,服务器将被启用自动重载功能启动,Play将检查您的项目,需要重新编译源代码。如果需要该应用程序会自动重新启动。
当出现:
[info] play - Listening for HTTP on /0.0.0.0:9000
(Server started, use Ctrl+D to stop and go back to the console...)
表示启动服务器在9000端口,在浏览器键入http://localhost:9000/ 看到:
Your new application is ready
这是在项目app/controller目录下有一个Application.scala:
package controllers
import play.api._
import play.api.mvc._
object Application extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))//改为中文
}
}
我们将输出改为中文:“这是我的项目.”
编译
Crtl-D回到控制台中断运行,输入:compile,出现如下错误:
[info] Compiling 1 Scala source to E:\temp\myFirstApp\target\scala-2.10\classes.
..
[error] IO error while decoding E:\temp\myFirstApp\app\controllers\Application.s
cala with UTF-8
[error] Please try specifying another one using the -encoding option
[error] one error found
[error] (compile:compile) Compilation failed
[error] Total time: 1 s, completed 2013-12-8 14:49:44
这个错误是Play将我们的模板文件翻译转换为Scala文件在目录myFirstApp\target\scala-2.10\src_managed\main\views\html下面,这些文件将被sbt 编译成.class文件,然后被play运行。SBT以默认的编码方式创建这些中间文件。
解决办法:设置环境JAVA_TOOL_OPTIONS为-Dfile.encoding=UTF8
然后重新再进入Play控制台,会看到picked up输出:
E:\temp>cd myFirstApp
E:\temp\myFirstApp>play
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
使用Eclipse
输入$eclipse,将我们的项目生成Eclipse项目,打开Eclipse导入即可。注意,eclipse的windows->preference-->General -->Workspace要设置为Utf-8,如下:
编译正常后,再次运行,浏览器出现:
Eclipse Scala插件
在http://scala-ide.org下载Eclipse的Scala插件。在eclipse -->install new software输入升级地址,会有很多,选择Scala IDE for scala.
应用案例
下面我们使用Play的WebServices library实现非堵塞的URL调用:
import play.api.mvc.{Controller, Action, Result}
import play.api.libs.ws.WS
import play.api.libs.json.Json
import play.api.libs.concurrent.Execution.Implicits._
import scala.concurrent.Future
object Race extends Controller {
def index() = Action {
Async {
val start = System.currentTimeMillis()
def getLatency(r: Any): Long = System.currentTimeMillis() - start
val googleTime = WS.url("http://www.google.com").get().map(getLatency)
val yahooTime = WS.url("http://www.yahoo.com").get().map(getLatency)
val bingTime = WS.url("http://www.bing.com").get().map(getLatency)
Future.sequence(Seq(googleTime, yahooTime, bingTime)).map { case times =>
Ok(Json.toJson(Map("google" -> times(0), "yahoo" -> times(1), "bing" -> times(2))))
}
}
}
}
这是统计调用三个网址的时间,通过异步获得统计结果。将这个Race加入Route:
GET /race controllers.Race.index()
浏览器调用http://localhost:9000/race ,可能会出现如下错误:
这是因为我们没有导入import play.api.libs.json.Json
重新运行,正常结果如下:
调试
输入$ play debug ,进入调试JPDA 模式。输出:
Listening for transport dt_socket at address: 9999
在Eclipse的debug configuration中,新增:
然后我们在Race的 val start = System.currentTimeMillis() 设置断点,运行run,在浏览器调用,Eclipse将自动在断点暂停,如下:我们可以跟踪当前的变量等。
Reactive Postgres with Play Framework & ScalikeJDBC