Play中JSON序列化

Posted 我自横刀向天笑 去留肝胆两昆仑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Play中JSON序列化相关的知识,希望对你有一定的参考价值。

根据经验Json处理是比较简单的,但是Play和akka-http的序列化让我烦恼了不少时间,所以我从自己的角度记录一下Play的JSON处理,代码也都是从官方文档复制后重新整理的,下面是参考的官方文档下有几篇JSON的文章

Working with Json

  1. JSON basics
  2. JSON with HTTP
  3. JSON Reads/Writes/Format Combinators
  4. JSON automated mapping
  5. JSON Transformers

实体序列化例子

1.本例中使用的实体类

package serialize

case class Location(lat: Double, long: Double)
case class Resident(name: String, age: Int, role: Option[String])
case class Place(name: String, location: Location, residents: Seq[Resident])

2.序列化例子

import play.api.libs.json._
import play.api.libs.functional.syntax._
import serialize.{Location, Place, Resident}

object PlayJsonTest{

  def main(args:Array[String]):Unit={

    implicit val locationReads = Json.reads[Location]
    implicit val residentReads = Json.reads[Resident]
    implicit val placeReads = Json.reads[Place]

    val json: JsValue = Json.parse("""
                  {
                    "name" : "Watership Down",
                    "location" : {
                      "lat" : 51.235685,
                      "long" : -1.309197
                    },
                    "residents" : [ {
                      "name" : "Fiver",
                      "age" : 4,
                      "role" : null
                    }, {
                      "name" : "Bigwig",
                      "age" : 6,
                      "role" : "Owsla"
                    } ]
                  }
                  """)

    val result: JsResult[Place] = Json.fromJson[Place](json)

    result match {
      case JsSuccess(r: Place, path: JsPath) => println("Name: " + r.name)
      case e: JsError => println("Errors: " + JsError.toJson(e).toString())
    }
  }
}

3.解释

一般的json序列化比较简单,有一个类似JsonManager的管理类,提供serialize(object obj)与deserialize<T>(string json)这样方法,一般不需要开发者做太多的工作,比较简单,也是基于这种认识,所以对play的json处理方式就会困惑。

原因是scala和akka系列声称自己是可伸缩的框架,面向大数据领域,他认为传统的方式是比较重的oo方式,而大数据的处理主要是批量处理数据,所以可能只是对批量数据的个别字段做简单的运算即可,不需要沉重的OOM,看他原文的描述:

Are we doomed to convert JSON to OO?

For a few years now, in almost all web frameworks (except recent javascript server side stuff maybe in which JSON is the default data structure), we have been used to get JSON from network and convert JSON (or even POST/GET data) into OO structures such as classes (or case classes in Scala). Why?

  • For a good reason : OO structures are “language-native” and allows manipulating data with respect to your business logic in a seamless way while ensuring isolation of business logic from web layers.
  • For a more questionable reason : ORM frameworks talk to DB only with OO structures and we have (kind of) convinced ourselves that it was impossible to do else… with the well-known good & bad features of ORMs… (not here to criticize those stuff)

Is OO conversion really the default use case?

In many cases, you don’t really need to perform any real business logic with data but validating/transforming before storing or after extracting. Let’s take the CRUD case:

  • You just get the data from the network, validate them a bit and insert/update into DB.
  • In the other way, you just retrieve data from DB and send them outside.

So, generally, for CRUD ops, you convert JSON into a OO structure just because the frameworks are only able to speak OO.

I don’t say or pretend you shouldn’t use JSON to OO conversion but maybe this is not the most common case and we should keep conversion to OO only when we have real business logic to fulfill.

 4.总结

先要知道play的json的关注点,以及他的思维方式,对于这种思维方式的好与坏,其实也无所谓。

以上是关于Play中JSON序列化的主要内容,如果未能解决你的问题,请参考以下文章

Play/Scala如何防止空数组的Json序列化?

使用 Play Framework JSON 库的自定义 Joda 时间序列化器?

从片段调用 Google Play 游戏服务

使用 Play-JSON 库解析对象序列

如何在 Play Framework JSON Rest 上使用 java.time.LocalDate?

Scala,使用 play 2.5 将 joda.LocalDateTime 转换为 json