33
31

More than 5 years have passed since last update.

play.api.libs.json.Jsonを使ったJsonシリアライズ(とデシリアライズ)

Posted at

scala周りはまだまだ発展途上なのかすぐに情報が陳腐化してしまい、ググッた情報が「ププッ 今どきそれやらねーよ」というのがしばしば。
Json周りはライブラリがたくさんあってよくワカランチンです。

時期による流行りなのか、人の好みなのか意見が分かれていてなんとも・・・。

まぁ、Play使ってるんだし標準のplay.api.libs.jsonパッケージでいいか、というお話です。

公式のドキュメントはこちら。
http://www.playframework-ja.org/documentation/2.1.5/ScalaJsonCombinators

object Jsonをつかってシリアライズ/デシリアライズ

やりたいのは case class をJSONシリアライズ/デシリアライズ(マーシャリングって言ったほうがいいの?)したいってことで、

  • Json#toJson でシリアライズ
  • Json#fromJson でデシリアライズ

が基本のようです。

Writes ,Reads を定義

JSONICのようにリフレクションを使ってよろしくやってくれるのかというとそうでもない。(sjsonはリフレクションでやるらしいが細かいこと見てない。)
ということで変換ルールを定義してやらなければならないようだ。

公式ドキュメントによると、

case_class
case class Creature(name:String,isDead:Boolean,weight:Float)
Reads
import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val creatureReads = (
  (__ \ "name").read[String] and
  (__ \ "isDead").read[Boolean] and
  (__ \ "weight").read[Float]
)(Creature)  
Writes
import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val creatureWrites = (
  (__ \ "name").write[String] and
  (__ \ "isDead").write[Boolean] and
  (__ \ "weight").write[Float]
)(unlift(Creature.unapply))

こんな感じでimplicitなreads,writesをスコープ内に宣言せよと。

…なんかめんどくせーよ

こ、これっていいの?? 何かDAOをめんどくせーなーと思いながら実装したあの日々が…。

と思ったらですね、

Json.scala
def reads[A]: Reads[A]
def writes[A]: Writes[A]

こんなのがあるんですよ。単純なReads,Writesなら生成してくれるようでホッとしました。

writesの例
scala> implicit val creatureWrites = Json.writes[Creature]
creatureWrites: play.api.libs.json.OWrites[Creature] = play.api.libs.json.OWrites$$anon$2@55093b47

scala> Json.toJson(Creature("Cow",true,456))
res73: play.api.libs.json.JsValue = {"name":"Cow","isDead":true,"weight":456.0}
readsの例
scala> implicit val creatureReads=Json.reads[Creature]
creatureReads: play.api.libs.json.Reads[Creature] = play.api.libs.json.Reads$$anon$8@4fcee80f
scala> val strJson = """
     | {"name":"Zombi","isDead":false,"weight":30.5}
     | """
strJson: String =
"
{"name":"Zombi","isDead":false,"weight":30.5}
"
scala> Json.fromJson(Json.parse(strJson))
res82: play.api.libs.json.JsResult[Creature] = JsSuccess(Creature(Zombi,false,30.5),)

JsResult

fromJsonを使った場合、JsResultというOption型みたいなやつがかえされる。
なんでもパースに失敗した時にJsError型を返すことで失敗した原因をうまいこと返す仕組みらしい。

33
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
31