用SBT和Play进行JSON序列化

简介: 版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。 https://blog.csdn.net/chszs/article/details/49722273 用SBT和Play进行JSON序列化作者:chszs,未经博主允许不得转载。
版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。 https://blog.csdn.net/chszs/article/details/49722273

用SBT和Play进行JSON序列化

作者:chszs,未经博主允许不得转载。经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs

本文主要讲述如何使用Play框架的JSON模块进行JSON的序列化和反序列化。

JSON数据是非常常见的数据类型,基本上做项目就离不开JSON。在Scala语言中,要处理JSON有多种方法,既可以利用Java相关的JSON库(比如Jackson或GSON)进行处理,又可以使用Scala语言的JSON库。那么,在这些库Spray JSON、Play JSON、Argonaut、Jackson、Rapture中,到底应该选择哪一个呢?

我分析了Scala领域的各种JSON库,最终决定使用Play JSON库作为我的首选工具。那么,怎样使用Play框架的JSON模块来完成任务,而无需引入整个Play框架呢?我找到了这个:Play JSON

一、Play JSON模块的使用

地址: http://mvnrepository.com/artifact/com.typesafe.play/play-json_2.11

当前Play JSON库的最新版本为2.4.3版。Maven库依赖如下:

<dependency>
    <groupId>com.typesafe.play</groupId>
    <artifactId>play-json_2.11</artifactId>
    <version>2.4.3</version>
</dependency>

可以下载这个JAR包,并加到项目类路径下。也可以使用SBT管理SCala项目,在SBT文件中添加Play JSON依赖:

name := "proectj-name"
version := "1.0"
scalaVersion := "2.11.7"
libraryDependencies ++= Seq("com.typesafe.play" % "play-json_2.11" % "2.4.3")

下面说明如何使用此库进行JSON的序列化和反序列化。

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

以上是账单模型的一部分——支付。它是我们进行JSON序列化和反序列化的一部分。

二、创建模型

下面为JSON数据创建对应的对象模型。

1、Address字段

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,目的是实现对象的序列化和反序列化。我仅仅简单的使用了strings、numbers、arrays和null值类型。

3、在父对象执行动作

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)
  }
}

看上面的代码,由于type是Scala的关键字,故使用了pType作为变量代替。还有手动定义了支付对象的读写操作。

三、序列化实例

为了检查序列化是否正常工作,可以创建单元测试。在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")
  }
}

四、总结

Play JSON库的功能足够强大,可以满足JSON相关的需求。要想了解更多内容,可以查看官方文档,见:
https://www.playframework.com/documentation/2.4.x/ScalaJson

目录
相关文章
|
3月前
|
XML 存储 JSON
Twaver-HTML5基础学习(19)数据容器(2)_数据序列化_XML、Json
本文介绍了Twaver HTML5中的数据序列化,包括XML和JSON格式的序列化与反序列化方法。文章通过示例代码展示了如何将DataBox中的数据序列化为XML和JSON字符串,以及如何从这些字符串中反序列化数据,重建DataBox中的对象。此外,还提到了用户自定义属性的序列化注册方法。
49 1
|
25天前
|
JSON JavaScript 前端开发
Go语言中json序列化的一个小坑,建议多留意一下
在Go语言开发中,JSON因其简洁和广泛的兼容性而常用于数据交换,但其在处理数字类型时存在精度问题。本文探讨了JSON序列化的一些局限性,并介绍了两种替代方案:Go特有的gob二进制协议,以及msgpack,两者都能有效解决类型保持和性能优化的问题。
49 7
|
29天前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
34 4
|
1月前
|
JSON JavaScript Java
对比JSON和Hessian2的序列化格式
通过以上对比分析,希望能够帮助开发者在不同场景下选择最适合的序列化格式,提高系统的整体性能和可维护性。
42 3
|
1月前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
1月前
|
JSON JavaScript 前端开发
|
3月前
|
JSON Go 数据格式
Golang语言结构体链式编程与JSON序列化
这篇文章是关于Go语言中结构体链式编程与JSON序列化的教程,详细介绍了JSON格式的基本概念、结构体的序列化与反序列化、结构体标签的使用以及如何实现链式编程。
46 4
|
3月前
|
JSON 数据格式
序列化 json和pickle
序列化 json和pickle
|
4月前
|
存储 JSON JavaScript
python序列化: json & pickle & shelve 模块
python序列化: json & pickle & shelve 模块
|
4月前
|
JSON Java 数据格式
【IO面试题 七】、 如果不用JSON工具,该如何实现对实体类的序列化?
除了JSON工具,实现实体类序列化可以采用Java原生序列化机制或第三方库如Protobuf、Thrift、Avro等。