当前位置: 首页 > 工具软件 > scala0.json > 使用案例 >

Scala:使用JSON

姬裕
2023-12-01

在软件开发过程中,使用JSON是非常常见的任务。 在Scala中,您可以通过多种方式来做到这一点,或者借助Java流行的库(例如Jackson)或使用Scala特定的库。 如何从Spray JSON, Play JSON ,Argonaut,Jackson,Rapture等中做出正确选择?

有一天,我接受了一次面试的测试任务。 根据它,我必须在电子商务环境中实现Checkout对象的JSON序列化和反序列化。 我分析了Scala的所有现有JSON库,并已将它们用作小样本,并决定采用Play JSON库进行此任务。 我这样做是因为它具有全面的文档和许多示例,它是最受欢迎的Scala Web框架的一部分,并且我喜欢它的API。

问题是如何在没有整个框架的情况下使用PlayFramework JSON模块。 而且我发现了一个单独的git仓库,其中包含完全使用Play JSON API。

对于那些想了解如何与Play Framework分开使用Play JSON模块的人,我继续阅读该文章。

如何使用Play JSON模块?

首先,您需要将Play JSON库添加到您的项目中。 您可以通过多种方式进行操作–下载lib的代码并将其包含在项目中,或使用某些依赖项管理工具。 我个人在Scala项目中使用SBT。

这就是我们可以将Play JSON依赖项添加到SBT文件中的方法:

name := "proectj-name"

version := "1.0"

scalaVersion := "2.11.7"

libraryDependencies ++= Seq("com.typesafe.play" % "play-json_2.11" % "2.4.2")

然后,您可能想看看如何使用此库执行JSON序列化和反序列化。 好吧,让我们做一个简短的演示。 这是JSON模型,我们需要使用它:

{
  "id": 1,
  "type": "credit card",
  "address": {
    "address1": "Baker str 3",
    "address2": "",
    "city": "London",
    "zipcode": "WC064"
  },
  "token": "u4lPaa74M"
  "cvv": 112
}

这是Checkout模型的一部分-付款。 首先,我们需要做什么才能对该JSON模型实现序列化和反序列化?

  1. 为JSON中最深的模型创建一个Scala模型。 这是“地址”字段的案例类:
    case class Address(address1: String,
                       address2: Option[String],
                       city: String,
                       state: String,
                       zipcode: String)
  2. 声明写入读取规则,这些规则用于将Scala模型写入JSON以及将JSON读取到Scala。 可以在Address对象中声明此逻辑:
    object Address {
    
      import play.api.libs.json._
    
      implicit val addressFormats = Json.format[Address]
    
      def writeAddress(address: Address) = {
        Json.toJson(address)
      }
    
      def readAddress(jsonAddress: JsValue) = {
        jsonAddress.as[Address]
      }
    
    }

    如您所见,我们使用Play对象Json ,以执行具有简单字段的对象的序列化和反序列化。 简单来说,我的意思是字符串,数字,数组和空值。

  3. 对父对象执行操作#1,#2。
    case class Payment(id: Long,
                       pType: String,
                       address: Address,
                       token: String,
                       cvv: String)
    
    object Payment {
    
      import play.api.libs.json._
    
      def writePayment(payment: Payment) = {
        JsObject(Seq(
          "id" -> JsNumber(payment.id),
          "type" -> JsString(payment.pType),
          "address" -> Json.toJson(payment.address),
          "token" -> JsString(payment.token),
          "cvv" -> JsString(payment.cvv)
        ))
      }
    
      def readPayment(jsonPayment: JsValue) = {
        val id = (jsonPayment \ "id").as[Long]
        val pType = (jsonPayment \ "type").as[String]
        val address = (jsonPayment \ "address").as[Address]
        val token = (jsonPayment \ "token").as[String]
        val cvv = (jsonPayment \ "cvv").as[String]
        Payment(id, pType, address, token, cvv)
      }
    
    }

    由于类型字段名称 ,我们在上面得到了更多详细的代码。 由于类型字在Scala中是保留字,因此我们不能将其用作Scala中变量的名称。 因此,我们必须为“付款”模型定义手动读取和写入。

如何在Scala中测试序列化和序列化?

为了检查一切正常,我们可以创建单元测试。 在SBT文件中添加ScalaTest依赖项。 现在看起来应该像这样:

name := "proectj-name"

version := "1.0"

scalaVersion := "2.11.7"

libraryDependencies ++= Seq(
  "org.scalatest" % "scalatest_2.11" % "3.0.0-SNAP5" % "test",
  "com.typesafe.play" % "play-json_2.11" % "2.4.2")

并为付款编写测试:

import models._
import models.Payment._

import org.scalatest._
import play.api.libs.json._

class PaymentTest extends FlatSpec with Matchers {

  val address = Address("1375 Burlingame Ave.", None, "Burlingame", "California", "94010")

  "Payment " should "be converted to JSON correctly " in {

    val payment = Payment(1, "creditCard", address, "wdweadowei3209423", "123")
    val paymentJSON = writePayment(payment)

    (paymentJSON \ ("id")).get should be (JsNumber(1))
    (paymentJSON \ ("type")).get should be (JsString("creditCard"))
    (paymentJSON \ ("address")).get should be (Json.toJson(payment.address))
    (paymentJSON \ ("token")).get should be (JsString("wdweadowei3209423"))
    (paymentJSON \ ("cvv")).get should be (JsString("123"))

  }

  it should " be deserialized correctly " in {
    val paymentJSON: JsValue = JsObject(Seq(
      "id" -> JsNumber(1),
      "type" -> JsString("creditCard"),
      "address" -> Json.toJson(address),
      "token" -> JsString("wdweadowei3209423"),
      "cvv" -> JsString("123")
    ))

    val payment = readPayment(paymentJSON)

    payment.id should be (1)
    payment.pType should be ("creditCard")
    payment.address should be (address)
    payment.token should be ("wdweadowei3209423")
    payment.cvv should be ("123")
  }

}

摘要

JSON Play模块非常强大。 我没有描述很多可以借助它来完成的事情。 但我建议您阅读官方文档,并在此查看更多示例。 要特别注意您阅读的文档版本和在项目中使用的Scala。

翻译自: https://www.javacodegeeks.com/2015/11/scala-working-with-json.html

 类似资料: