博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Play中JSON序列化
阅读量:5162 次
发布时间:2019-06-13

本文共 4778 字,大约阅读时间需要 15 分钟。

总的来说在scala体系下,对于习惯了java和c#这些常规开发的人来说,无论是akka-http还是play,就处理个json序列化与反序列化真他娘够费劲的。

根据经验,Json处理是比较简单的,但是Play和akka-http的序列化让我烦恼了不少时间,所以我从自己的角度记录一下Play的JSON处理,来理解play的思维方式。

一、官方文档

代码也都是从官方文档复制后重新整理的,下面是参考的下有几篇JSON的文章

Working with Json

二、实体序列化例子

1.本例中使用的实体类

package serializecase 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,看他原文的描述:

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)

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的关注点,以及他的思维方式,对于这种思维方式的好与坏,其实也无所谓。

 

三、json4s

json4s是scala下使用OO方式可以很接近的方法,他也提供了一些play.json关注的类xpath查询的这种功能,

在akka-http下实在是无法忍受从1个到24个类属性序列化的这种方式,所以可以是一个比较好的选择

json4s的sbt引用

"org.json4s" %% "json4s-jackson" % "3.6.2",

本例使用的实体还是上文的实体,对应的序列化代码为:

 
package org.netsharp.jsonoom import java.text.SimpleDateFormat import org.json4s._ import org.json4s.jackson.JsonMethods._ import org.json4s.jackson.Serialization object Json4sDemo {
def main(args:Array[String]):Unit={
var json:String = """ {
"name" : "Watership Down", "location" : {
"lat" : 51.235685, "long" : -1.309197 }, "residents" : [ {
"name" : "Fiver", "age" : 4, "role" : null }, {
"name" : "Bigwig", "age" : 6, "role" : "Owsla" } ] } """; // implicit val formats = Serialization.formats(NoTypeHints) implicit val formats = new DefaultFormats {
override def dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") } var place:Place = Serialization.read[Place](json) json = Serialization.write(place) println(json) //另外一种序列化接口 place = parse(json).extract[Place] } }
 

总的来说,json4s和play.json思路类似,他们都是基于jackson的序列化

你说是不是play.json抄袭了json4s?

四、直接用Jackson进行序列化

这篇文章介绍了直接

但是也不是那么完美,集合只能用java的集合,bean不能使用Option[Double]这样的类型

 

转载于:https://www.cnblogs.com/Netsharp/p/9938917.html

你可能感兴趣的文章
Nginx反向代理的基本配置
查看>>
SpringMvc文件资源防止被外链链接
查看>>
WCF、WebAPI、WCFREST、WebService之间的区别
查看>>
设计模式 -- 单例模式
查看>>
Linux下安装 php imagick扩展
查看>>
git出现: not a git repository
查看>>
appium 问题
查看>>
go条件语句
查看>>
css使用的三种方式
查看>>
C#中Const和Readonly的区别
查看>>
Noip2016day2 组合数问题problem
查看>>
django中widget小部件
查看>>
训练记录
查看>>
使用 Windows Live ID 登录 Windows 8---------互联网时代的云端革命
查看>>
横屏模式注意点
查看>>
虚拟机对网卡的设置
查看>>
after()和inserAfter(),before()和inserBefore()区别
查看>>
JDBC——释放资源的代码
查看>>
bootstrap模态框垂直居中
查看>>
用数据管理过程(3)——可预测级别的量化管理(麦当劳的管理方式)
查看>>