本文的目標是經過一個用戶登陸示例,簡要的介紹使用Play進行Web開發的基本流程。本文並不會手把手教你如何建立一個Play應用,而是經過核心的代碼片斷傳遞Play的一些設計理念,爲不熟悉Play框架的同窗提供一個快速瞭解的途徑。html
在controllers
目錄下建立ApplicationController
類:api
package controllers import play.api.mvc._ class ApplicationController extends Controller { def login = Action { Ok(views.html.login("用戶登陸")) } def doLogin(userName: String, password: String) = Action { val mess = userName + "&" + password Ok(mess) } }
上面定義了login
和doLogin
兩個Action,一個用於引導用戶至登陸頁面,另外一個用戶處理登陸請求。一個Action其實就是一個函數,接受一個request做爲參數,返回一個Result,返回的Result最終會被以Http響應的形式寫回給瀏覽器。Ok(mess)
返回的結果就是Result類型。瀏覽器
不熟悉Scala的同窗看上面的代碼會感受比較奇怪,
Action{...}
和Ok(...)
是什麼鬼?其實這是調用單例對象上apply
方法的簡寫形式,即Action{...}
等價於Action.apply(...)
,Ok(...)
等價於Ok.apply(...)
。省略掉.apply
是否是看起來感受舒服一點^_^。 另外Scala不建議使用return
語句,默認最後一條語句的值做爲函數的返回值。多線程
在views
目錄下建立login.scala.html
:mvc
@(title: String) <!DOCTYPE html> <html lang="en"> <head><title>@title</title></head> <body> <form action="/doLogin"> <input name="userName" type="text" placeholder="User Name" /> <input name="password" type="password" placeholder="Password" /> <button type="submit">當即登陸</button> </form> </body> </html>
咱們知道模板頁面中有兩部份內容,一部分是不可變的Html內容,另外一部分是須要動態執行的代碼。而神奇的@
符號就是要告訴Play,它後面跟着的是須要動態執行的代碼。在Play中,一個模板文件就是一個函數,接受一組參數,返回動態執行後的Html內容,函數名就是不帶後綴的文件名,例如上面定義的模板文件編譯後生成的函數名稱是login
。模板文件的第一行用於指明函數的參數列表,上面的模板文件至關於定義了一個login(title: String)
函數。app
把View抽象成函數好處仍是不少的,例如組合多個View變成了函數之間的相互調用,另外咱們也可使用多線程加速大頁面的渲染。 Play的模板層採用
Scala
語言編寫,藉助Scala語言,在Play的模板層你會感受本身像是一隻脫了繮的野馬。其實在模板層只須要了解Scala的if
和for
語法便可。Scala雖然入門門檻較高,可是帶來的收益是巨大的,隨着你對Play瞭解的深刻必定能夠慢慢的體會到這點。框架
Play使用routes文件定義Http請求和Action之間的映射關係,編輯conf/routes
文件,添加一行:函數
GET /login controllers.ApplicationController.login GET /doLogin controllers.ApplicationController.doLogin(userName: String, password: String)
進入命令行,執行activator run
,在瀏覽器中打開http://localhost:9000/login
: 單元測試
一般登陸操做使用Post請求,因此咱們調整一下routes:測試
POST /doLogin controllers.ApplicationController.doLogin
ApplicationController
代碼調整以下:
package controllers import play.api.mvc._ import play.api.data._ import play.api.data.Forms._ class ApplicationController extends Controller { def login = Action { Ok(views.html.login("用戶登陸")) } def doLogin = Action { implicit request => val loginForm = Form( tuple( "userName" -> email, "password" -> text(minLength = 6) ) ) loginForm.bindFromRequest().fold( errorForm => Ok(errorForm.errors.toString()), tupleData => { val (userName, password) = tupleData Ok(userName + "&" + password) } ) } }
上面的fold
函數用於處理表單參數驗證經過和不經過兩種狀況。
經過上面簡單的登陸示例咱們會發現,Play中Controller和View是兩個獨立的模塊,之間沒有任何耦合。Controller完成一些業務運算,而後將數據以參數的形式傳遞給View,View沒有任何的內置對象,全部的依賴都定義在參數列表中,Controller和View之間只是簡單的函數調用關係,狀態經過函數參數進行傳遞,這樣的好處是程序執行流程容易追蹤,代碼容易閱讀,而且單元測試會變得很是簡單,固然最大的好處是多線程環境下代碼無需同步,極大地提升了執行效率。另外Play在改動代碼後無需重啓,直接刷新瀏覽器就能夠了,開發體驗仍是不錯的。