akka2.5_播放2.0:Akka,Rest,Json和依赖项

akka2.5

在过去的几个月中,我越来越多地涉足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}
}

很多代码,但是我想向您展示演员定义以及如何使用它们。 总结一下,使用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

akka2.5

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357498.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第三周学习进度条

第三周 所花时间(包括上课) 26 代码量(行) 253 博客量(篇) 2 了解到的知识点 第一次团队合作,发现要学习的东西还很多,合作伙伴之间还是需要磨合的,两个人之间还是需要沟通的,果然容易打起来。。。 知识上进一步了解了栈…

javaScript实现E-mail 验证

下面的函数检查输入的数据是否符合电子邮件地址的基本语法。 意思就是说,输入的数据必须包含 符号和点号 (.)。同时, 不可以是邮件地址的首字符,并且 之后需有至少一个点号: function validateForm(){var xdocument.forms["…

计算机硬件知识竞赛题库,电脑知识竞赛题库.pdf

1.在下列系统中, ( )是实时系统。A. 计算机激光照排系统 B.航空定票系统 C.办公自动化系统 D.计算机辅助设计系统答案: B2.操作系统是一种 ( ) 。A. 应用软件 B .系统软件 C.通用软件 D &#x…

代码挑战“ Vrolijke Framboos”事后验尸

星期二,我们在JDriven举行了第二次“ Vrolijke Framboos”(快乐树莓的荷兰语)Java代码挑战赛 ,这是爆炸性的! 今年的挑战是创建一个REST服务客户端,该客户端将与服务器一起玩猜数字游戏。 设置会话后&#…

电子门锁没电的解决办法

导读:今天对象回家,输入电子门锁密码怎么也打不开,指示灯也不亮,前段时间也时不时的能按,我就预感到电池没电了,那么我是如何进入家门的呢? 一般这种电子门锁可以输入密码,也可以使用机械钥匙。说实话,这钥匙在哪我压根没见过,租的房子,房东都不知道,只能输入密码才…

oracle学习笔记系列------oracle 基本操作之表的增删改查

--创建一个表 CREATE TABLE employee_souvc(id NUMBER(4),name VARCHAR2(20),gender CHAR(1),birth DATE,salary NUMBER(6,2),job VARCHAR2(30),deptno NUMBER(2) ); --DESC table_name:查看表结构,看到表的列的名字,以及对应的类型,长度等 DESC employe…

【前端笔试题】文本居中的几种小技巧

前端面试或者开发总会遇到是文本居中的情况及场景,这里一起总结一下。便于查找和使用。 目录 方法一 方法二 方法三 方法四 方法一 自动外边距 div #container{margin-left:auto;margin-right:auto;width:168px;} 方法二 使用text-align body{text-align:center;}

计算机专业常用图论,同等学力申硕计算机专业--数学公式集合(新增学习笔记)...

组合数学部分:基础公式:定义:从n个不同的元素中, 取r个并按次序排列, 称为从n中取r个的一个排列, 全部这样的排列数记为P(n, r).定义: 从n个不同的元素中, 取r个但是不考虑次序时候, 称为从n中取r个的一个组合, 全部这样的组合总数记为C(n, r).定义: 从n…

使用Ubuntu22+Minikube快速搭建K8S开发环境

安装Vmware 这一步,可以参考我的如下课程。 安装Ubuntu22 下载ISO镜像 这里我推荐从清华镜像源下载,速度会快非常多。 下载地址:https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/22.04.3/ 如果你报名了我的这门视频课程&#xf…

linux内核分析——扒开系统调用的三层皮(上)

20135125陈智威 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 系统调用:库函数封装了系统调用,通过库函数和系统调用打交道 用户态:低级别执行状态,代码的掌控范围会受到限…

前端常见浏览器兼容性问题及解决办法

不同浏览器的内核也不尽相同,所以各个浏览器对网页的解析存在一定的差异。 1.不同浏览器的标签默认的外补丁和内补丁不同 *{ margin:0; padding:0; } 2. 块属性标签float后,又有横行的margin情况下,在IE6显示margin比设置的大 style{ disp…

unchecked异常_为什么要在Java中使用Unchecked异常而不是Checked异常

unchecked异常关于检查与未检查的异常的争论可以追溯到过去。 有人说这是Java包含的最佳功能之一。 其他人则说这是他们最大的错误之一[ 1 ]。 辩论似乎结束了。 在这篇文章中,我将尝试包含涉及该主题的文章和书籍的链接。 我不是专家,但是我会尽力向您解…

微型计算机系统中的内部寄存,微机原理与接口技术习题集汇总.doc

微机原理与接口技术习题集汇总.doc (50页)本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!29.9 积分.word格式,第二章 微机基本组成及工作原理1.1微型机的基本结构一、单项选择题1&#xf…

10个对Web开发者最有用的Python包

Python最近成为了开发人员最喜欢的语言之一。无论你是专业的,业余的,还是一个初学者,你都可以从Python语言及其程序包中受益。Python已经被证明是当今最具活力的面向对象的编程语言之一。这就是为什么即使是世界顶级公司也广泛使用这种语言的…

移动端适配的几种解决办法

所谓移动端适配,就是WebApp在不同尺寸的屏幕上等比显示 原则 开发时方便,写代码时设置的值要和标注的 160px 相关方案要适配大多数手机屏幕,并且无 BUG用户体验要好,页面看着没有不适感思路 写页面时,按照设计稿写固定宽度,最后再统一缩放处理,在不同手机上都能用按照设…

真正释放Maven和Java EE的强大功能

如果野心和愿景太复杂而无法使用,那么它们可能会毁灭伟大的解决方案。 尽管Maven和Java EE是在整个Java行业中都已建立的良好技术,但是使用它们并使用其作者希望您使用的所有技术和模式来设计项目可能非常棘手。 在开发过程中途,由于一开始就…

浙江丽水学院计算机专业,2019丽水学院专业排名

丽水学院是一所公办全日制普通本科高校,地处浙江绿谷、瓯江之畔、国家级生态示范区——丽水市。为了让大家更好的了解这所大学的专业排名,下面是学习啦小编给大家带来的丽水学院专业排名,供大家参考!丽水学院王牌专业名单省级重点专业&#x…

开发高性能JAVA应用程序基础(内存篇)

虽然JAVA的垃圾回收和当前高配置的服务器可以让程序员大部分时间忘掉OutOfMemoryError的存在,但是访问量增大后频繁的GC会额外消耗CPU (使用top查看结果为us值高),系统响应速度下降,积压的请求又会占用更多内存从而恶性循环,严重时…

【前端面试题】2021/3/12挺经典的面试题,这个经历很深刻。

今天面试去啦,填了职业性格测试,人格测试及招聘的基本经历信息,面试官是技术头头,柔中带钢,问题润物细无声的感觉,很考验基本功。 上午10:30面试了一个达达的前端,采用的是线上腾讯会议的方式&a…

html5 ios cookie,ios – WKWebView,获取所有cookie

我想从WKWebView获取所有cookie.为什么?我已经启动了一个使用基于Web的身份验证的项目.因此,我应该拦截cookie以确保用户已登录并用于其他目的.另一种情况 – 想象一下,如果用户登录,而不是“杀死”应用程序 – 由于存储此cookie会话的一些延迟将丢失:(.The problem…