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.pswp.cn/news/393487.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/393487.shtml
英文地址,請注明出處:http://en.pswp.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…