美文网首页ScalaPlay FrameworkScala
Play Scala 2.5.x - Play JSON开发指南

Play Scala 2.5.x - Play JSON开发指南

作者: joymufeng | 来源:发表于2017-03-17 15:20 被阅读784次

    1 JSON开发简介

    Play提供了一套基于jackson开发的JSON库,帮助开发者便捷地处理JSON数据。目前Play的JSON库可以实现以下功能:

    • 自动完成JSON对象和case class之间的双向转换
    • 验证JSON数据的合法性
    • 直接作为HTTP的请求/响应数据,方便开发RESTful服务

    目前Play的JSON库已经分离成独立项目,所以你可以很容易地将它引入到自己的项目:

    libraryDependencies += "com.typesafe.play" %% "play-json" % playVersion
    

    2 基本JSON类型

    JsValuetrait是所有基本JSON类型的父类型,JSON库提供的基本类型如下:

    • JsString
    • JsNumber
    • JsBoolean
    • JsObject
    • JsArray
    • JsNull

    在日程开发中,我们很少跟这些JSON基本类型打交道。因为在Play中对于基本类型T(例如String, Int, ...)以及Seq[T]已经提供了默认的隐式转换, 可以自动将其转换成对应的JSON类型,例如:

    //基本类型值
    Json.obj("name" -> JsString("joymufeng"))
    //可以简写成:
    Json.obj("name" -> "joymufeng")
    
    //序列类型值
    Json.obj("emails" -> JsArray(Seq(JsString("a"), JsString("b"))))
    //可以简写成:
    Json.obj("emails" -> Seq("a", "b"))
    

    在Play的JSON库里,整形和浮点型都使用JsNumber表示,这是一个略为糟糕的设计,因为会导致JSON数据无法在多语言环境下共享。例如通过Java代码向MongoDB写入了一个整形数值,但是经过Play的JSON库修改后变成了浮点型,Java代码再次读取时便会报错。

    3 基本的JSON操作

    • 构建一个JsObject对象
      //直接构建
      val json = 
          Json.obj(
            "name" -> "joymufeng", 
            "emails" -> Json.arr("joymufeng@163.com"), 
            "address" -> Json.obj(
                "province" -> "JiangSu", 
                "city" -> "NanJing"
            )
          )
      //从JSON字符串构建
      val json = 
          Json.parse("""
            {
                "name": "joymufeng", 
                "emails": ["joymufeng@163.com"], 
                "address": {
                    "province": "JiangSu", 
                    "city" -> "NanJing"
                }
            }
          """)
      
    • 常用操作
      //read props
      val city = (json \ "address" \ "city").as[String]
      val cityOpt = (json \ "address" \ "city").asOpt[String]
      val emails = (json \ "emails").as[List[String]]
      
      //mutable
      var obj = Json.obj("a" -> 1)
      obj ++= Json.obj("b" -> 2)  //obj: {"a":1,"b":2}
      
      //pretty print
      val prettyStr = Json.prettyPrint(obj)
      

    4 JSON对象和case class互转

    Play虽然为基本类型T以及Seq[T]提供了默认的隐式转换,但是case class的隐式转换需要我们自己声明,例如我们有如下两个case class:

    case class Address(province: String, city: String)
    case class Person(name: String, emails: List[String], address: Address)
    

    我们只需要声明两个隐式的Format对象就可以了:

        import play.api.libs.json._
        implicit val addressFormat = Json.format[Address]
        implicit val personFormat = Json.format[Person]
    
        //case class -> JSON object
        val person = Person("joymufeng", List("joymufeng@163.com"), Address("JiangSu", "NanJing"))
        val json = Json.toJson[Person](person)
    
        //JSON object -> case class
        val p1 = Json.fromJson[Person](json).get
        val p2 = json.as[Person]
        val p3 = json.asOpt[Person].get
    

    我们发现Json.fromJson[Person](json)返回的类型并不是Person而是JsResult[Person],这是因为从JSON object到case class的转换可能会发生错误,JsResult有两个子类JsSuccessJsError,分别用来处理成功和失败两种情况:

        Json.fromJson[Person](json) match {
          case p: JsSuccess[Person] => println(p)
          case e: JsError => println(e.errors)
        }
    

    5 小结

    随着NoSQL的不断普及,JSON数据在Web开发中显得越来越重要。使用Play提供的JSON库可以大大简化日常的开发工作。另外还有一些基于JSON库的第三方模块,例如Play-ReactiveMongo,利用该模块将Play和MongoDB完美结合,开发出高性能的异步非阻塞系统。

    相关文章

      网友评论

      • 63659e883e47:play 1.4.0返回json一样的嘛?
        63659e883e47: @joymufeng 嗯嗯,我1都还没学好。。。正在努力当中
        joymufeng:不一样,play 2 和 1 差别很大。

      本文标题:Play Scala 2.5.x - Play JSON开发指南

      本文链接:https://www.haomeiwen.com/subject/wpventtx.html