播放2.0:Akka,Rest,Json和依賴項

在過去的幾個月中,我越來越多地涉足scala。 Scala與“ Play框架”一起為您提供了一個非常有效且快速的開發環境(即,您掌握了Scala語言的特質之后)。

Play框架背后的家伙一直在努力開發新版本的Play 2.0。 在Play 2.0中,scala扮演著更為重要的角色,尤其是整個構建過程得到了極大的改進。 到目前為止,Play 2.0遇到的唯一問題是缺少好的文檔。 你們在努力更新Wiki方面很努力,但是要獲得所需的內容,仍然經常需要反復試驗。 但是請注意,這通常不只是由Play引起的,我有時仍然會遇到更奇特的Scala構造;-)

在本文中,我將向您介紹如何使用Scala在Play 2.0中完成一些常見任務。 更具體地說,我將向您展示如何創建一個應用程序:

  • 使用基于sbt的依賴性管理來配置外部依賴性
  • 使用play eclipsify命令在Eclipse中(帶有Scala-ide插件)進行編輯
  • 使用Play的路線提供Rest API
  • 使用Akka 2.0(由Play框架提供)異步調用數據庫并生成Json(正因為我們可以)
  • 使用Play提供的Json功能(基于jerkson)將Scala對象轉換為Json

我不會讓使用牢騷的數據庫訪問,如果您想了解更多關于看看這個文章。 我想將Querulous代碼轉換為使用Anorm。 但是由于我最后一次與Anorm的經歷是,我該如何說服我,而不是令人信服的積極,所以將其保存下來供以后使用。

使用Play 2.0創建應用程序

使用Play 2.0進行安裝和運行非常容易,并且有據可查,因此我不會在此花費太多時間。 有關完整說明,請參見Play 2.0 Wiki 。 要啟動并運行,請先下載并提取Play 2.0,然后執行以下步驟:

從控制臺執行以下命令:

$play new FirstStepsWithPlay20

這將創建一個新項目,并向您顯示以下輸出:

_ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/ play! 2.0-RC2, http://www.playframework.orgThe new application will be created in /Users/jos/Dev/play-2.0-RC2/FirstStepsWithPlay20What is the application name? 
> FirstStepsWithPlay20Which template do you want to use for this new application? 1 - Create a simple Scala application2 - Create a simple Java application3 - Create an empty project> 1OK, application FirstStepsWithPlay20 is created.Have fun!

現在,您已經可以運行一個應用程序。 轉到剛剛創建的目錄并執行播放運行。

$ play run[info] Loading project definition from /Users/jos/Dev/play-2.0-RC2/FirstStepsWithPlay2/project
[info] Set current project to FirstStepsWithPlay2 (in build file:/Users/jos/Dev/play-2.0-RC2/FirstStepsWithPlay2/)--- (Running the application from SBT, auto-reloading is enabled) ---[info] play - Listening for HTTP on port 9000...(Server started, use Ctrl+D to stop and go back to the console...)

如果導航到http:// localhost:9000 ,則可以看到第一個Play 2.0應用程序。 至此,Play 2.0的基本安裝已完成。

依賴管理

我在引言中提到我不是從頭開始這個項目的。 我將用Play 1.2.4,Akka 1.x,JAX-RS和Json-Lift開發的Rest服務重寫為Play 2.0框架提供的組件。 由于依賴管理在Play 1.2.4和Play 2.0之間發生了變化,因此我需要使用所需的依賴來配置新項目。 在Play 2.0中,您可以在名為build.scala的文件中執行此操作,您可以在項目的項目文件夾中找到該文件。 在添加上一個項目的依賴關系后,該文件如下所示:

import sbt._
import Keys._
import PlayProject._object ApplicationBuild extends Build {val appName         = "FirstStepsWithPlay2"val appVersion      = "1.0-SNAPSHOT"val appDependencies = Seq("com.twitter" % "querulous" % "2.6.5" ,"net.liftweb" %% "lift-json" % "2.4" ,"com.sun.jersey" % "jersey-server" % "1.4" ,"com.sun.jersey" % "jersey-core" % "1.4" , "postgresql" % "postgresql" % "9.1-901.jdbc4")val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings(// Add extra resolver for the twitter  resolvers += "Twitter repo" at "http://maven.twttr.com/" ,resolvers += "DevJava repo" at "http://download.java.net/maven/2/")
}

閱讀sbt文檔(http://code.google.com/p/simple-build-tool/wiki/LibraryManagement )后,如何使用此文件非常簡單。 基本上,我們使用appDependencies定義了所需的庫,并定義了一些額外的存儲庫,其中sbt應該從中下載其依賴項(使用解析器)。 值得一提的是,您可以在定義依賴項時指定%%。 這意味著我們還想搜索與我們的scala版本匹配的庫。 SBT查看我們當前配置的版本,并為該版本添加限定符。 這可以確保我們得到一個適用于我們的Scala版本的版本。
就像我提到的,我想用Play 2.0的功能替換我使用的大多數外部庫。 刪除我不再使用的內容后,該文件如下所示:

import sbt._
import Keys._
import PlayProject._object ApplicationBuild extends Build {val appName         = "FirstStepsWithPlay2"val appVersion      = "1.0-SNAPSHOT"val appDependencies = Seq("com.twitter" % "querulous" % "2.6.5" ,"postgresql" % "postgresql" % "9.1-901.jdbc4")val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings(// Add extra resolver for the twitter  resolvers += "Twitter repo" at "http://maven.twttr.com/")
}

配置依賴項后,我可以為我的IDE配置該項目。 盡管我的所有同事都是IntelliJ的擁護者,但我仍然會回到以前的習慣:Eclipse。 因此,讓我們看看您需要做些什么才能在Eclipse中啟動和運行該項目。

從Eclipse工作

在我的Eclipse版本中,我安裝了scala插件 ,而Play 2.0框架可以很好地與該插件一起使用。 要使您的項目在eclipse中運行,您所要做的就是運行以下命令:play eclipsify

jos@Joss-MacBook-Pro.local:~/dev/play-2.0-RC2/FirstStepsWithPlay2$ ../play eclipsify
[info] Loading project definition from /Users/jos/Dev/play-2.0-RC2/FirstStepsWithPlay2/project
[info] Set current project to FirstStepsWithPlay2 (in build file:/Users/jos/Dev/play-2.0-RC2/FirstStepsWithPlay2/)
[info] About to create Eclipse project files for your project(s).
[info] Compiling 1 Scala source to /Users/jos/Dev/play-2.0-RC2/FirstStepsWithPlay2/target/scala-2.9.1/classes...
[info] Successfully created Eclipse project files for project(s): FirstStepsWithPlay2
jos@Joss-MacBook-Pro.local:~/dev/play-2.0-RC2/FirstStepsWithPlay2$

現在,您可以使用Eclipse中的“導入項目”,并且可以直接從Eclipse中編輯Play 2.0 / Scala項目。 可以直接從Eclipse啟動Play環境,但是我還沒有使用過。 我只是從命令行啟動Play項目,一次,我在Eclipse中所做的所有更改都立即可見。 對于那些與Play玩了更長的時間的人來說,這可能不再那么特別了。 就我個人而言,我仍然對這種環境的生產力感到驚訝。

使用Play的路線提供Rest API

在我以前的Play項目中,我使用jersey模塊能夠使用JAX-RS批注指定我的Rest API。 由于Play 2.0包含許多重大的API更改,并且幾乎是從頭開始的重寫,因此您不能指望所有舊模塊都能正常工作。 Jersey模塊也是如此。 我確實深入研究了該模塊的代碼,以查看更改是否微不足道,但是由于找不到關于如何為Play 2.0創建插件以允許您與路線處理進行交互的文檔,因此我決定只切換到Play 2.0可以休息的方式。 使用“ routes”文件,可以很容易地將我只暴露給一個簡單控制器的兩個操作連接起來:

# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~GET     /resources/rest/geo/list    controllers.Application.processGetAllRequest
GET     /resources/rest/geo/:id     controllers.Application.processGetSingleRequest(id:String)

相應的控制器如下所示:

package controllersimport akkawebtemplate.GeoJsonService
import play.api.mvc.Action
import play.api.mvc.Controllerobject Application extends Controller {val service = new GeoJsonService()def processGetSingleRequest(code: String) = Action {val result = service.processGetSingleRequest(code)Ok(result).as("application/json")}def processGetAllRequest() = Action {val result = service.processGetAllRequest;Ok(result).as("application/json");} 
}

如您所見,我剛剛創建了非常簡單的基本操作。 還沒有研究過錯誤和異常處理,但是Play提供的Rest API確實使使用附加的Rest框架變得不必要。 多數民眾贊成在第一個框架。 我的原始應用程序的下一部分需要更改的是Akka代碼。 Play 2.0包含Akka庫的最新版本(2.0-RC1)。 由于我的原始Akka代碼是針對1.2.4編寫的,因此存在許多沖突。 更新原始代碼并不是一件容易的事。

使用Akka 2.0

我不會深入探討Akka 2.0遇到的所有問題。 最大的問題是Play Wiki上的文檔非常糟糕,Akka網站上的文檔非常糟糕,而我在Akka文檔中找到正確信息的技能也很糟糕。 與我一起僅使用Akka大約三四個月,并不能使其成為最佳組合。 經過幾個小時的挫折之后,我才刪除了所有現有的Akka代碼,并從頭開始。 20分鐘后,我使用Akka 2進行了所有工作,并使用了Play的主配置。 在下一個清單中,您可以看到相應的代碼(我有意離開了導入,因為在很多示例中您都可以找到它們,因此將它們省略了,這很容易,但要困難得多)

import akka.actor.actorRef2Scala
import akka.actor.Actor
import akka.actor.Props
import akka.dispatch.Await
import akka.pattern.ask
import akka.util.duration.intToDurationInt
import akka.util.Timeout
import model.GeoRecord
import play.libs.Akka
import resources.commands.Command
import resources.commands.FULL
import resources.commands.SINGLE
import resources.Database/*** This actor is responsible for returning JSON objects from the database. It uses querulous to * query the database and parses the result into the GeoRecord class.*/
class JsonActor extends Actor {/*** Based on the type recieved we determine what command to execute, most case classes* can be executed using the normal two steps. Execute a query, convert result to* a set of json data and return this result.*/def receive = {// when we receive a Command we process it and return the resultcase some: Command => {// execute the query from the FULL command and process the results using the// processRows functionvar records:Seq[GeoRecord] = null;// if the match parameter is null we do the normal query, if not we pass in a set of varargssome.parameters match {case null =>  records = Database.getQueryEvaluator.select(some.query) {some.processRows}case _ => records = Database.getQueryEvaluator.select(some.query, some.parameters:_*) {some.processRows}}// return the result as a json stringsender ! some.toJson(records)}case _ => sender ! null}
}/*** Handle the specified path. This rest service delegates the functionality to a specific actor* and if the result from this actor isn't null return the result*/
class GeoJsonService {def processGetSingleRequest(code: String) = {val command = SINGLE();command.parameters = List(code);runCommand(command);}/*** Operation that handles the list REST command. This creates a command* that forwards to the actor to be executed.*/def processGetAllRequest:String = {runCommand(FULL());}/*** Function that runs a command on one of the actors and sets the response*/private def runCommand(command: Command):String =  {// get the actorval actor = Akka.system.actorOf(Props[JsonActor])implicit val timeout = Timeout(5 seconds)val result = Await.result(actor ? command, timeout.duration).asInstanceOf[String]// return result as Stringresult}
}

很多代碼,但是我想向您展示actor的定義以及如何使用它們。 總結一下,使用Akka執行請求/回復模式所需的Akka 2.0代碼是這樣的:

private def runCommand(command: Command):String =  {// get the actorval actor = Akka.system.actorOf(Props[JsonActor])implicit val timeout = Timeout(5 seconds)val result = Await.result(actor ? command, timeout.duration).asInstanceOf[String]// return result as Stringresult}

這使用全局Akka配置來檢索所需類型的actor。 然后,我們向演員發送命令,并返回一個Future,在其上我們等待5秒鐘的結果,然后將其轉換為String。 此未來等待我們的演員發送回復。 這是在actor本身中完成的:

sender ! some.toJson(records)

替換了Akka之后,我終于有了一個工作系統。 瀏覽Play 2.0上的文檔時,我注意到他們從2.0開始提供了自己的Json庫。 由于我在先前版本中使用了Json-Lift,因此我認為將代碼移到Play提供的名為Jerkson的Json庫中是一個不錯的練習。

搬到杰克森

遷移到新圖書館很容易。 Lift-Json和Jerkson都使用幾乎相同的概念來構建Json對象。 在舊版本中,我沒有使用任何自動編組(因為我必須遵守jsongeo格式),因此在此版本中,我也手動進行了編組。 在下一個清單中,您可以同時看到舊版本和新版本。正如您所看到的,兩者中使用的概念幾乎相同。

#New version using jerksonval jsonstring = JsObject(List("type" -> JsString("featureCollection"),"features" -> JsArray(records.map(r =>(JsObject(List("type" -> JsString("Feature"),"gm_naam" -> JsString(r.name),"geometry" -> Json.parse(r.geojson),"properties" -> ({ var toAdd = List[(String, play.api.libs.json.JsValue)]()r.properties.foreach(entry => (toAdd ::= entry._1 -> JsString(entry._2)))JsObject(toAdd)}))))).toList)))#Old version using Lift-Jsonval json =("type" -> "featureCollection") ~("features" -> records.map(r =>(("type" -> "Feature") ~("gm_naam" -> r.name) ~("geometry" -> parse(r.geojson)) ~("properties" -> ({// create an empty objectvar obj = JNothing(0)// iterate over the propertiesr.properties.foreach(entry => (// add each property to the object, the reason// we do this is, that else it results in an // arraylist, not a list of seperate propertiesobj = concat(obj, JField(entry._1, entry._2))))obj})))))

畢竟,我擁有的已經完全一樣。 但是現在使用Play 2.0,并且不使用任何外部庫(Querulous除外)。 到目前為止,我在Play 2.0方面的經歷非常積極。 缺少好的具體示例和文檔有時會令人討厭,但可以理解。 它們確實在分發中提供了幾個廣泛的示例,但沒有與我的用例匹配的示例。 因此,對負責Play 2.0的人表示敬意。 到目前為止,我所看到的是,出色而全面的框架,許多功能以及一個可以進行scala編程的良好環境。在接下來的幾周中,我將看看是否有足夠的勇氣開始使用Anorm,并且我將看看Play在客戶端可以提供什么。 到目前為止,我已經看過我真正喜歡的LESS,因此我對他們的模板解決方案充滿了希望;-)

參考: 播放2.0:Akka,Rest,Json和我們JCG合作伙伴的 依賴項 ? Smart Java博客中的Jos Dirksen。


翻譯自: https://www.javacodegeeks.com/2012/03/play-20-akka-rest-json-and-dependencies.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373749.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373749.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373749.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python使用多線程寫生成器_Python學習——多線程,異步IO,生成器,協程

Python的語法是簡潔的,也是難理解的。比如yield關鍵字:def fun():for i in range(5):print(test)x yield iprint(good, x)if __name__ __main__:a fun()# print(a.__next__())# print(a.__next__())# print(a.__next__())y a.send(None)y a.send(-1…

Python與C++結構體交互

需求:根據接口規范,實現與服務端的數據交互 服務端結構體分包頭、包體、包尾 包頭C結構體示例如下 1 typedef struct head2 {3 BYTE string1;4 BYTE string2; //包類型5 BYTE string3; //版本號,目前為06 char s…

Ubuntu下安裝OpenSSH Server并在客戶端遠程連接Ubuntu

本文主要是向讀者介紹了如何在Ubuntu系統下安裝OpenSSH Server并在客戶端遠程連接Ubuntu,共有兩種方法,一種是命令行安裝;另一種是通過Ubuntu Software Center安裝,希望對大家能有幫助! 方法一(推薦&#…

算法:老鼠走迷宮問題

算法:老鼠走迷宮問題(初) 【寫在前面】 老鼠走迷宮問題的遞歸實現,是對遞歸思想的一種應用。 【問題描述】 給定一個二維數組,數組中2表示墻壁,0表示通路,由此數組可展示為一個迷宮圖。給定入口位置和出口位置&#xf…

rust python對比_Python Rust 迭代器對比

迭代是數據處理的基石,而 Python 中所有集合都可以迭代,這是 Python 讓使用者感到非常方便的特征之一。下面是一些在 Python 中經常使用的迭代模式# 列表for i in [1, 2, 3, 4]:print(i)# 字典di {a: 1, b: 2, c: 3}# 迭代鍵for k in di.keys():print(k…

WebSphere Application Server性能調整工具包

IBM已發布了WebSphere Application Server性能調整工具包 ,該工具包具有從Eclipse工作區*監視多個 WebSphere Application Server的功能。 該工具使用WAS Performance Monitoring統計信息來獲取并繪制圖表,以指示服務器的運行狀況。 *請注意,…

CentOS 配置防火墻操作實例(啟、停、開、閉端口)

CentOS 配置防火墻操作實例&#xff08;啟、停、開、閉端口&#xff09;&#xff1a; 注&#xff1a;防火墻的基本操作命令&#xff1a; 查詢防火墻狀態: [rootlocalhost ~]# service iptables status<回車> 停止防火墻: [rootlocalhost ~]# service iptables stop &…

linux常用命令-壓縮解壓命令

壓縮解壓命令 目錄 1. 壓縮解壓命令&#xff1a;gzip 2. 壓縮解壓命令&#xff1a;gunzip 3. 壓縮解壓命令&#xff1a;tar 4. 壓縮解壓命令&#xff1a;zip 5. 壓縮解壓命令&#xff1a;unzip 6. 壓縮解壓命令&#xff1a;bzip2 7. 壓縮解壓命令&#xff1a;bunzip2 1. 壓縮解…

達夢數據庫查詢數據庫所有表名_達夢數據庫的一些實用小SQL

1)當前數據庫中的模式名&#xff1a;select distinct object_name TABLE_SCHEMA from all_objects where object_type SCH;2)查出各模式對應的用戶&#xff1a;selectSCH_OBJ.NAME ,SCH_OBJ.ID ,SCH_OBJ.CRTDATE,USER_OBJ.NAMEfrom(select NAME, ID, PID, CRTDATE from …

設置Java EE 6開發環境

本教程簡要說明了如何設置典型的環境來開發基于Java EE 6的應用程序。 除了可以正常工作的Windows XP客戶端具有足夠的CPU能力和內存外&#xff0c;本教程沒有其他先決條件。 在教程中&#xff0c;我們將需要安裝以下組件&#xff1a; Java 6 JDK更新26 用于Java EE開發人員的…

css cursor url用法格式詳解

css cursor url用法格式&#xff1a;css:{cursor:url(圖標路徑),auto;} //IE,FF,chrome瀏覽器都可以 實例代碼&#xff1a;html{cursor: url("http://ued.taobao.com/blog/wp-content/themes/taobaoued/images/cursor.ico"),auto;} 解析&#xff1a;前面的url是自定義…

iostext添加點擊事件_iOS開發小技巧 - label中的文字添加點擊事件

Label中的文字添加點擊事件以前老師講過類似的功能,自己懶得回頭看了,找了很多第三方的,感覺這個小巧便利,作者只是擴展了分類,實現起來代碼也少.先來個效果圖自己的項目,直接上代碼- (void)setTopicModel:(CYQTopicModel *)topicModel{_topicModel topicModel;NSArray *likeA…

ubantu下安裝Nginx

Nginx 概述 Nginx ("engine x") 是一個高性能的 HTTP 和 反向代理 服務器&#xff0c;也是一個 IMAP/POP3/SMTP 代理服務器。 Nginx 是由 Igor Sysoev 為俄羅斯訪問量第二的 Rambler.ru 站點開發的&#xff0c;第一個公開版本0.1.0發布于2004年10月4日。其將源代碼…

Hadoop中的問題–何時無法交付?

Hadoop是很棒的軟件。 它不是原始的&#xff0c;但肯定不能消除它的榮耀。 它建立在并行處理的基礎上&#xff0c;這個概念已經存在了數十年。 Hadoop雖然從概念上來說并不是獨創性的&#xff0c;但它顯示了自由開放的力量&#xff08;就像在啤酒中一樣&#xff01;&#xff09…

創建 dblink

目的&#xff1a;oracle中跨數據庫查詢 兩臺數據庫服務器db_A(本地)和db_B(遠程192.168.1.100)&#xff0c;db_A下用戶user_a 需要訪問到db_B下user_b的數據解決&#xff1a;查詢得知使用dblink(即database link 數據庫鏈)實現過程&#xff1a;1、確定用戶user_a有沒有創…

C#靜態常量和動態常量的區別

C#擁有兩種不同的常量&#xff1a;靜態常量(compile-time constants)和動態常量(runtime constants)。它們有不同的特性&#xff0c;錯誤的使用不僅會損失效率&#xff0c;還可能造成錯誤。相比之下&#xff0c;靜態常量在速度上會稍稍快一些&#xff0c;但是靈活性卻比動態常…

spring的鉤子_高級java開發必須掌握的Spring接口——SmartLifecycle

有些場景我們需要在Spring 所有的bean 完成初始化后緊接著執行一些任務或者啟動需要的異步服務。 常見有幾種解決方案j2ee 注解 啟動前PostConstruct 銷毀前PreDestroy 基于j2ee 規范springboot 的 org.springframework.boot.CommandLineRunner springboot 特性前面我已經介紹過…

Java:對Java SE 6和Java SE 7的客戶端和桌面部分的改進!

Java 6和Java 7中的客戶端改進 了解有關Java SE 6和Java SE 7的客戶端和桌面部分的改進&#xff0c;包括新的applet插件&#xff0c;Java Deployment Toolkit&#xff0c;成形和半透明的窗口&#xff0c;重量級-輕量級混合以及Java Web Start。 介紹 自2006年12月發布Java平臺…

辨異 —— 行星 vs 恒星

star&#xff1a;恒星&#xff0c;planet&#xff1a;行星&#xff1b;1. 恒星 恒星是指宇宙中靠核聚變產生的能量而自身能發熱發光的星體&#xff08;比如太陽&#xff09;。過去天文學家以為恒星的位置是永恒不變的&#xff0c;以此為名。但事實上&#xff0c;恒星也會按照一…

軟件公司職責分配

崗位&#xff1a;項目經理 主要職責&#xff1a;1、 計劃&#xff1a;a)項目范圍、項目質量、項目時間、項目成本的確認。b)項目過程/活動的標準化、規范化。c)根據項目范圍、質量、時間與成本的綜合因素的考慮&#xff0c;進行項目的總體規劃與階段計劃。d)各項計劃得到上級領…