博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spray.json_如何使用Spray-json(Un)在Akka HTTP中封送JSON
阅读量:2520 次
发布时间:2019-05-11

本文共 7317 字,大约阅读时间需要 24 分钟。

spray.json

by Miguel Lopez

由Miguel Lopez

如何使用Spray-json(Un)在Akka HTTP中封送JSON (How to (Un)marshal JSON in Akka HTTP with spray-json)

In the , we added JSON support to our Akka HTTP API using circe.

在一篇 ,我们使用circe将JSON支持添加到了Akka HTTP API中。

This time we’ll do the same but using spray-json. Akka HTTP supports it by providing an official library — we don’t need a third-party party one like we did with circe.

这次我们将执行相同的操作,但使用spray-json。 Akka HTTP通过提供一个官方库来支持它-我们不需要像circe那样的第三方。

项目设置 (Project setup)

We’ll go through the same steps as the previous tutorial to set up the project.

我们将按照与上一教程相同的步骤来设置项目。

Clone the , and check out the branch 3.3-repository-implementation.

克隆 ,并检查了分支3.3-repository-implementation

We will also do the changes we did in the previous tutorial.

我们还将进行上一教程中所做的更改。

First, we will replace the circe dependencies with the spray-json dependency since we won’t be needing it for this tutorial. Update the build.sbt file with the following contents:

首先,我们将用circle-json依赖关系替换circe依赖关系,因为本教程将不需要它。 使用以下内容更新build.sbt文件:

name := "akkahttp-quickstart"version := "0.1"scalaVersion := "2.12.6"val akkaVersion = "2.5.13"val akkaHttpVersion = "10.1.3"libraryDependencies ++= Seq(  "com.typesafe.akka" %% "akka-actor" % akkaVersion,  "com.typesafe.akka" %% "akka-testkit" % akkaVersion % Test,  "com.typesafe.akka" %% "akka-stream" % akkaVersion,  "com.typesafe.akka" %% "akka-stream-testkit" % akkaVersion % Test,  "com.typesafe.akka" %% "akka-http" % akkaHttpVersion,  "com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVersion % Test,  "com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion,  "org.scalatest" %% "scalatest" % "3.0.5" % Test)

Next, we will add a save function to the TodoRepository and its implementation:

接下来,我们将save函数添加到TodoRepository及其实现中:

import scala.concurrent.{ExecutionContext, Future}trait TodoRepository {  def all(): Future[Seq[Todo]]  def done(): Future[Seq[Todo]]  def pending(): Future[Seq[Todo]]  def save(todo: Todo): Future[Todo]}class InMemoryTodoRepository(initialTodos: Seq[Todo] = Seq.empty)(implicit ec: ExecutionContext) extends TodoRepository {  private var todos: Vector[Todo] = initialTodos.toVector  override def all(): Future[Seq[Todo]] = Future.successful(todos)  override def done(): Future[Seq[Todo]] = Future.successful(todos.filter(_.done))  override def pending(): Future[Seq[Todo]] = Future.successful(todos.filterNot(_.done))  override def save(todo: Todo): Future[Todo] = Future.successful {    todos = todos :+ todo    todo  }}

This will allow us to create a POST request to create new todos.

这将允许我们创建一个POST请求来创建新的待办事项。

And finally, update the Main object to create a list of todos for testing purposes, and with the appropriate routes:

最后,更新Main对象以创建用于测试目的的待办事项列表,并使用适当的路由:

import akka.actor.ActorSystemimport akka.http.scaladsl.Httpimport akka.stream.ActorMaterializerimport scala.concurrent.Awaitimport scala.util.{Failure, Success}object Main extends App {  val host = "0.0.0.0"  val port = 9000  implicit val system: ActorSystem = ActorSystem(name = "todoapi")  implicit val materializer: ActorMaterializer = ActorMaterializer()  import system.dispatcher  val todos = Seq(    Todo("1", "Record amazing gifs for the tutorials", "", done = false),    Todo("2", "Finish the spray-json tutorial", "", done = true),  )  val todoRepository = new InMemoryTodoRepository(todos)  import akka.http.scaladsl.server.Directives._  def route = path("todos") {    get {      complete(todoRepository.all())    } ~ post {      entity(as[Todo]) { todo =>        complete(todoRepository.save(todo))      }    }  }  val binding = Http().bindAndHandle(route, host, port)  binding.onComplete {    case Success(_) => println("Success!")    case Failure(error) => println(s"Failed: ${error.getMessage}")  }  import scala.concurrent.duration._  Await.result(binding, 3.seconds)}

With this in place, we can now move to support JSON parsing.

有了这个,我们现在可以支持JSON解析了。

创建格式 (Creating the format)

The project shouldn’t be compiling right now because Akka HTTP doesn’t know how to convert JSON to our models and vice versa.

该项目不应立即编译,因为Akka HTTP不知道如何将JSON转换为我们的模型,反之亦然。

Adding JSON support with circe was quite simple. It only involved adding a couple of import statements.

使用circe添加JSON支持非常简单。 它只涉及添加几个导入语句。

Sadly, with spray-json that isn’t the case. The effort isn’t that great either.

可悲的是,使用Spray-json并非如此。 努力也不是很好。

So, let’s start.

所以,让我们开始吧。

Because we want to use spray-json with Akka HTTP, we can look at the on how to accomplish what we want.

因为我们要在Akka HTTP上使用spray-json,所以我们可以查看 ,了解如何完成我们想要的。

We need to extend the trait SprayJsonSupport to let Akka HTTP know how to parse our models to and from JSON (via the FromEntityUnmarshaller and ToEntityMarshaller provided by the trait).

我们需要扩展特征SprayJsonSupport以使Akka HTTP知道如何与JSON解析模型(通过ToEntityMarshaller提供的FromEntityUnmarshallerToEntityMarshaller )。

And to create the actual format, we will use the trait DefaultJsonProtocol from spray-json.

为了创建实际的格式 ,我们将使用spray-json中的特征DefaultJsonProtocol

Add the following object below the Todo model:

Todo模型下面添加以下对象:

object TodoFormat extends SprayJsonSupport with DefaultJsonProtocol {  implicit val todoFormat = jsonFormat4(Todo)}

This is the extra step we need when using spray-json. It has to be done for every model we have.

这是使用spray-json时需要的额外步骤。 必须为我们拥有的每个模型完成此操作。

To get our project working, we need to import TodoFormat in our Main object:

为了使我们的项目正常工作,我们需要在我们的Main对象中导入TodoFormat

import TodoFormat._import akka.http.scaladsl.server.Directives._def route = path("todos") {  get {    complete(todoRepository.all())  } ~ post {    entity(as[Todo]) { todo =>      complete(todoRepository.save(todo))    }  }}

Run the application and it should be working fine.

运行该应用程序,它应该可以正常工作。

Let’s make some tests!

让我们做一些测试!

测试我们的API (Testing our API)

We need to make sure our API is working as intended. So let’s query it as we did in the previous tutorial to check the functionality is the same.

我们需要确保我们的API能够按预期工作。 因此,让我们像上一教程中那样查询它,以检查功能是否相同。

Sending a GET request to localhost:9000/todos should give us the initial todos:

发送GET请求到localhost:9000/todos应该给我们初始的待办事项:

Great, that works the same.

太好了,工作原理是一样的。

Let’s see if sending invalid JSON gives us something similar:

让我们看看是否发送无效的JSON给我们带来了类似的效果:

It does. The error message is different but we get the same 400 Bad Request which is the important part.

是的 错误消息是不同的,但我们得到相同的400 Bad Request ,这是重要的部分。

Let’s create a new todo with valid JSON:

让我们使用有效的JSON创建一个新的待办事项:

And to finish off, let’s query the todos again to make sure it was saved:

最后,让我们再次查询待办事项以确保已保存:

There we go. We have a working application with spray-json.

好了 我们有一个使用Spray-json的应用程序。

Cool, isn’t it?

不错,不是吗?

结语 (Wrapping up)

Even though working with spray-json involves some extra manual work, you don’t need an additional third-party dependency to get it to work with Akka HTTP.

即使使用spray-json涉及一些额外的手动工作,您也不需要额外的第三方依赖关系即可使其与Akka HTTP一起使用。

It’s a matter of preference really.

这确实是一个优先事项。

In the future, we will explore how to accomplish different use cases with both to compare them. So stay tuned!

将来,我们将探索如何完成不同的用例并将它们进行比较。 敬请期待!

If you liked this tutorial and wanted to learn how to build an API for a todo application, check out our new free course! ???

如果您喜欢本教程,并且想学习如何为待办事项应用程序构建API,请查看我们的新免费课程! ???

Originally published at .

最初在发布。

翻译自:

spray.json

转载地址:http://ougwd.baihongyu.com/

你可能感兴趣的文章
vue2.0的ajax
查看>>
Promise预处理回调函数
查看>>
CSS 实现加载动画之二-圆环旋转
查看>>
sublime快捷键整理
查看>>
生产者消费者模型
查看>>
apiCloud 双击事件
查看>>
C#开发微信门户及应用(6)--微信门户菜单的管理操作
查看>>
查看变更(git diff)
查看>>
c++实现单向链表的一些操作
查看>>
Vim中无法用Alt键来映射
查看>>
ubuntu硬件配置查看命令
查看>>
第十二周作业
查看>>
DBSCAN算法的Java,C++,Python实现
查看>>
设置JPA的Query返回Map对象
查看>>
史上最简单MySQL教程详解(进阶篇)之存储过程(二)
查看>>
stack
查看>>
js 压缩
查看>>
oracle数据库----笔记1---PL/SQL基础5---子程序
查看>>
OpenCV学习笔记(二)——OpenCV环境变量配置
查看>>
二叉树遍历(flist)(已知中序和按层遍历,求先序 )
查看>>