spray.json_如何使用Spray-json(Un)在Akka HTTP中封送JSON

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 previous post, 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 repo, 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 Akka HTTP’s official docs on how to accomplish what we want.

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

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,请查看我们的新免费课程! ???

Akka HTTP QuickstartLearn how to create web applications and APIs with Akka HTTP in this free course!link.codemunity.io

Akka HTTP快速入门 在此免费课程中,了解如何使用Akka HTTP创建Web应用程序和API! link.codemunity.io

Originally published at www.codemunity.io.

最初在www.codemunity.io上发布。

翻译自: https://www.freecodecamp.org/news/how-to-un-marshal-json-in-akka-http-with-spray-json-1407876373a7/

spray.json

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

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

相关文章

React单元测试:Jest + Enzyme(二)

前言 在上一篇教程中,我们成功搭建了基于Jest和Enzyme的单元测试框架并成功地跑起来第一个单元测试,可以点击这里回顾一下。今天,我们重点讨论如何通过Jest来mock数据。 什么是Mock Mock的简单翻译就是模拟。既可以模拟数据,也可以…

input file 文件上传,js控制上传文件的大小和格式

文件上传一般是用jquery的uploadify,比较好用。后面会出文章介绍uploadify这个插件。 但是,有时候为了偷懒,直接就用input 的file进行文件和图片等的上传,input file 可以控制上传的格式,但是是html5,很多浏…

leetcode面试题 17.08. 马戏团人塔(二分法)

有个马戏团正在设计叠罗汉的表演节目,一个人要站在另一人的肩膀上。出于实际和美观的考虑,在上面的人要比下面的人矮一点且轻一点。已知马戏团每个人的身高和体重,请编写代码计算叠罗汉最多能叠几个人。 示例: 输入:…

如何选择适合自己的CMS建站系统

如今做网站已不像过去那样必须找网站公司才能建,因为网上针对建站的各种CMS建站系统层出不穷。像PageAdmin、DEDECMS、帝国CMS、Discuz等,这些CMS系统各有各的特点和优势,小熊优化的小编我从事网站制作和网站优化多年,和很多建站朋…

python dict hash算法_2020年3月26日python学习笔记——hash

什么是哈希?hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远…

数据处理不等式:Data Processing Inequality

我是在差分隐私下看到的,新解决方案的可用性肯定小于原有解决方案的可用性,也就是说信息的后续处理只会降低所拥有的信息量。 那么如果这么说的话为什么还要做特征工程呢,这是因为该不等式有一个巨大的前提就是数据处理方法无比的强大&#x…

aws架构_如何使用AWS构建可扩展架构

aws架构What I learned building the StateOfVeganism ?我学到的建立素食主义的方法是什么? By now, we all know that news and media shape our views on the topics we discuss. Of course, this is different from person to person. Some might be influence…

gulp 实现sass自动化 ,监听同步

实现功能 监听scss文件   sass自动化 准备条件 1 .安装gulp npm init ---->一直enter,会在当前目录下生成一个package.json文件,记录安装的依赖模块 npm install gulp --save-dev 2 .安装gulp-ruby-sass npm install gulp-ruby-sass 你还需要安装ruby环境…

leetcode面试题 10.03. 搜索旋转数组(二分法)

搜索旋转数组。给定一个排序后的数组,包含n个整数,但这个数组已被旋转过很多次了,次数不详。请编写代码找出数组中的某个元素,假设数组元素原先是按升序排列的。若有多个相同元素,返回索引值最小的一个。 示例1: 输入…

MSSQL → 02:数据库结构

一、数据库的组成 在SQL Server 2008中,用户如何访问及使用数据库,就需要正确了解数据库中所有对象及其设置。数据库就像一个容器,它里面除了存放着数据的表之外,还有视图、存储过程、触发器、约束等数据库对象。数据库管理的核心…

JAVA拳皇_拳皇(Java简单的小程序)代码实例|chu

刚开始学习Java,看完老九君的视频根据他的内容敲的代码,感觉还挺有成就感的,毕竟刚学习Java。package helloasd;import java.util.*; public class hellojava { public static void main(String[] args) { Scanner input new Scanner(System…

mySQL教程 第9章 触发器

第9章 触发器 入的新数据放到new表,删除的数据放到old表。 准备本章学习环境 连接数据库schoolDB,删除表TStudent,TScore和Tsubject中的所有数据。 delete from TStudent; delete from TScore; delete from TSubject; 向学生表插入两条记录 i…

vue使用python_如何使用Python和Vue创建两人游戏

vue使用pythonby Neo Ighodaro由新Ighodaro 如何使用Python和Vue创建两人游戏 (How to create a two-player game with Python and Vue) In this tutorial, we will create a realtime tic-tac-toe game using Python and Pusher channels. Here’s a demo of how the game wi…

掩码图制作photoshop__新手用

1.首先你得有一张图,比如这样的: 2.用PS打开他 3.左边工具栏里(快速选择工具W),选想显示的部分 4.ctrlc复制一下,新建一张黑底图粘贴上去或者白底图时选中显示区即花瓣右键反向右键填充成黑色 5.菜单栏->…

leetcode287. 寻找重复数(二分法)

给定一个包含 n 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。 示例 1: 输入: [1,3,4,2,2] 输出: 2 代码 class Solution {…

os-enviroment

pip3 install PyUserInput ping 是不带协议的转载于:https://www.cnblogs.com/liuweimingcprogram/p/10957592.html

java 压缩 乱码_如何解决java压缩文件乱码问题

用java来打包文件生成压缩文件,有两个地方会出现乱码:内容的中文乱码问题:修改sun的源码。使用开源的类库org.apache.tools.zip.ZipOutputStream和org.apache.tools.zip.ZipEntry,这两个类ant.jar中有,可以下载使用即可…

Unity3D手机斗地主游戏开发实战(02)_叫地主功能实现

大体思路 前面我们实现了点击开始游戏按钮,系统依次给玩家发牌的逻辑和动画,并展示当前的手牌。这期我们继续实现接下来的功能--叫地主。 1.首先这两天,学习了DOTween,这是一个强大的Unity动画插件,大家可以参考&#…

TensorFlow 学习(十)—— 工具函数

1. 基本 tf.clip_by_value() 截断,常和对数函数结合使用 # 计算交叉熵crose_ent -tf.reduce_mean(tf.log(y_*tf.clip_by_value(y, 1e-10, 1.))) a tf.reshape(tf.range(6, dtypetf.float32), [2, 3]) tf.clip_by_value(a, 2.5, 4.5) # 将值限定在 2.5 …

delphi5开发人员指南_非设计人员的网页设计开发人员指南

delphi5开发人员指南I created my first website as a school project when I was 14. The task was simple: create a very basic site including some text, images, and a table. My usual attitude to school projects was to completely forget about them and later come…