30天挑戰的最後一天,我決定學習Play Framework.我原本想寫Sacla,可是研究幾個小時後,我發現無法在一天內公正評價Scala,下個月花些時間來了解並分享經驗。本文咱們先來看看Play框架基礎,再開發個程序。css
Play是一個開源的現代web框架,用Java和Scala寫可擴展的web程序。它能自動加載更新使得極大提升生產率。Play設計了無狀態,非阻塞的架構,這使得用Play框架開發水平擴展web程序很容易。 html
我學習Play的緣由:前端
本文,咱們來開發一個網摘程序,容許用戶發佈和分享連接,你能夠在OpenShift上看在線程序。這和咱們以前第22天開發的程序同樣,你能夠參考以前的用例來更好了解。 java
請參考文檔瞭解怎樣安裝Play框架。 git
介紹完基礎,咱們來開始寫程序。 github
在你機器上運行如下命令。web
$ play new getbookmarks _ _ __ | | __ _ _ _ | '_ \| |/ _' | || | | __/|_|\____|\__ / |_| |__/ play 2.2.1 built with Scala 2.10.2 (running Java 1.7.0_25), http://www.playframework.com The new application will be created in /Users/shekhargulati/dev/challenges/30days30technologies/day30/blog/getbookmarks What is the application name? [getbookmarks] > Which template do you want to use for this new application? 1 - Create a simple Scala application 2 - Create a simple Java application > 2 OK, application getbookmarks is created. Have fun!
如上,輸入命令後,Play框架會問幾個問題。首先是程序的名字,而後是咱們是否想建立一個Scala程序或者Java程序。默認使用文件夾名做爲程序名,咱們選擇第二個選項來建立Java程序。 數據庫
以上命令新建了一個目錄getbookmarks,生成一下文件和目錄。json
如今咱們能夠運行Play建立的默認程序,打開play控制檯,運行play命令,而後用run命令。後端
$ cd getbookmarks $ play [info] Loading project definition from /Users/shekhargulati/dev/challenges/30days30technologies/day30/blog/getbookmarks/project [info] Set current project to getbookmarks (in build file:/Users/shekhargulati/dev/challenges/30days30technologies/day30/blog/getbookmarks/) _ _ __ | | __ _ _ _ | '_ \| |/ _' | || | | __/|_|\____|\__ / |_| |__/ play 2.2.1 built with Scala 2.10.2 (running Java 1.7.0_25), http://www.playframework.com > Type "help play" or "license" for more information. > Type "exit" or use Ctrl+D to leave this console. [getbookmarks] $ run [info] Updating {file:/Users/shekhargulati/dev/challenges/30days30technologies/day30/blog/getbookmarks/}getbookmarks... [info] Resolving org.fusesource.jansi#jansi;1.4 ... [info] Done updating. --- (Running the application from SBT, auto-reloading is enabled) --- [info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000 (Server started, use Ctrl+D to stop and go back to the console...)
如今能夠看到程序 http://localhost:9000.
這個程序,咱們只有一個域類, Story. 新建一個包模塊而後新建Java類。
package models; import play.db.ebean.Model; import javax.persistence.Entity; import javax.persistence.Id; import java.util.Date; @Entity public class Story extends Model{ @Id private String id; private String url; private String fullname; private Date submittedOn = new Date(); private String title; private String text; private String image; public Story() { } public Story(String url, String fullname) { this.url = url; this.fullname = fullname; } public Story(String url, String fullname, String image, String text, String title) { this.url = url; this.fullname = fullname; this.title = title; this.text = text; this.image = image; } // Getter and Setter removed for brevity }
以上代碼定義了一個簡單的JPA實體,用了@Entity和Id JPA註釋,Play用它本身的ORM層Ebean, 每一個實體類都擴展基礎模塊類。
Ebean默認是沒激活的,要激活它,打開程序conf, 取消下面這行的註釋。
ebean.default="models.*"
如今來激活程序的數據庫,Play框架提供了內置支持的H2數據庫,要激活它,打開程序conf文件,取消如下兩行的註釋。
db.default.driver=org.h2.Driver db.default.url="jdbc:h2:mem:play"
如今刷新瀏覽器能夠看到以下異常。
點擊Apply this script now使SQL更新生效。
本文,咱們開發了和第22天相同的程序,這個程序有AngularJS後端和REST後端,咱們用Play框架寫REST後端,從新用AngularJS後端,在conf/routes文件裏,複製粘貼一下代碼。
# Routes # This file defines all application routes (Higher priority routes first) # ~~~~ # Home page GET / controllers.Assets.at(path="/public", file="/index.html") GET /api/v1/stories controllers.StoryController.allStories() POST /api/v1/stories controllers.StoryController.submitStory() GET /api/v1/stories/:storyId controllers.StoryController.getStory(storyId) # Map static resources from the /public folder to the /assets URL path GET /assets/*file controllers.Assets.at(path="/public", file)
以上代碼:
如今在控制器包裏新建Java類,複製粘貼如下代碼到StoryController.java 文件。
package controllers; import com.fasterxml.jackson.databind.JsonNode; import models.Story; import play.api.libs.ws.Response; import play.api.libs.ws.WS; import play.db.ebean.Model; import play.libs.Json; import play.mvc.BodyParser; import play.mvc.Controller; import play.mvc.Result; import play.mvc.Results; import scala.concurrent.Await; import scala.concurrent.Future; import scala.concurrent.duration.Duration; import java.util.List; import java.util.concurrent.TimeUnit; public class StoryController { public static Result allStories(){ List<Story> stories = new Model.Finder<String , Story>(String.class, Story.class).all(); return Results.ok(Json.toJson(stories)); } @BodyParser.Of(BodyParser.Json.class) public static Result submitStory(){ JsonNode jsonNode = Controller.request().body().asJson(); String url = jsonNode.findPath("url").asText(); String fullname = jsonNode.findPath("fullname").asText(); JsonNode response = fetchInformation(url); Story story = null; if(response == null){ story = new Story(url,fullname); }else{ String image = response.findPath("image").textValue(); String text = response.findPath("text").textValue(); String title = response.findPath("title").textValue(); story = new Story(url,fullname, image , text , title); } story.save(); return Results.created(); } public static Result getStory(String storyId){ Story story = new Model.Finder<String, Story>(String.class, Story.class).byId(storyId); if(story == null){ return Results.notFound("No story found with storyId " + storyId); } return Results.ok(Json.toJson(story)); } private static JsonNode fetchInformation(String url){ String restServiceUrl = "http://gooseextractor-t20.rhcloud.com/api/v1/extract?url="+url; Future<Response> future = WS.url(restServiceUrl).get(); try { Response result = Await.result(future, Duration.apply(30, TimeUnit.SECONDS)); JsonNode jsonNode = Json.parse(result.json().toString()); return jsonNode; } catch (Exception e) { e.printStackTrace(); return null; } } }
以上代碼:
我決定從新用第22天寫的AngularJS前端,第22天展現了咱們怎樣用AngularJS和Java Spring框架,最好的部分是用JavaScript MV*框架,若是你的程序仍是用REST接口客戶端需求,你能夠再用前端代碼。詳情參考第22天文章。
如今刷新瀏覽器訪問程序 http://localhost:9000/
這就是今天的內容,但願你喜歡這個系列。
原文:https://www.openshift.com/blogs/day-30-play-framework-a-java-developer-dream-framework