play Framework play json

   概述


    使用JSON的推薦方式是使用 Play 的基於類的JSON庫,位於play.api.libs.json下. 

    該庫構建於Jerkson之上,它是一個Scala包裝者,基於一個超快的基於Java的JSON庫,Jackson.

    這種方式的好處是,Java和Scala可以共享同樣的庫(Jackson),而Scala用戶可以享受額外類型安全的好處。 
    play.api.libs.json包中,包含了7個JSON數據類型: 
        JsObject 
        JsNull 
        JsUndefined 
        JsBoolean 
        JsNumber 
        JsArray 
        JsString 
    
    它們都繼承自JsValue。 
    
    解析JSON字符串 

    你可以將任何的JSON字符串解析成JsValue。 
?
1
valjson:JsValue =Json.parse(jsonString)

    遍歷JSON樹


    只要你擁有一個JsValue,你就可以遍歷該樹。該API看起來很像Scala提供的使用NodeSeq遍歷XML文檔的方式. 
?
1
2
3
4
valjson =Json.parse(jsonString)
 
valmaybeName =(json \ "user"\ name).asOpt[String]
valemails =(json \ "user"\\ "emails").map(_.as[String])

   注意使用 \ 遍歷不會導致失敗.你必須在末尾使用 asOpt[T]自行處理出錯誤情形,它將返回 None 如果值缺失的話.否則,你可以使用 as[T],以拋異常的方式處理失敗,如果值丟失的話. 

    Scala值轉成Json 

    As soon as you have a type class able to transform the Scala type to Json, it is pretty easy to 

    generate any Scala value to Json. For example letʼs create a simple Json object:

    只要你有一個type class 你就能將Scala類型轉成Json,很容易將任何的Scala值轉成Json.例如讓我們創建一個簡單的Json對象:

?
1
valjsonNumber =Json.toJson(4)

  或者創建Json數組

?
1
valjsonArray =Json.toJson(Seq(1234))
    這裏將Seq[Int]轉成Json數組沒任何問題。然而當Seq由異構的值組成時,情況將變得複雜: 
?
1
valjsonArray =Json.toJson(Seq(1"Bob"34))
    沒辦法將Seq[Any]轉成Json。(Any可以是任何非Json格式支持的對象,對吧?) 

    簡單的選擇是將它們做爲Seq[JsValue]處理: 
?
1
2
3
valjsonArray =Json.toJson(Seq(
  toJson(1), toJson("Bob"), toJson(3), toJson(4)
))
    現在讓我們看看最後一個創建更復雜的Json對象的例子: 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
valjsonObject =Json.toJson(
  Map(
    "users"-> Seq(
      toJson(
        Map(
          "name"-> toJson("Bob"),
          "age"-> toJson(31),
          "email"-> toJson("[email protected]")
        )
      ),
      toJson(
        Map(
          "name"-> toJson("Kiki"),
          "age"-> toJson(25),
          "email"-> JsNull
        )
      )
    )
  )
)

    它將產生如下Json結果: 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
valjsonObject =Json.toJson(
  Map(
    "users"-> Seq(
      toJson(
        Map(
          "name"-> toJson("Bob"),
          "age"-> toJson(31),
          "email"-> toJson("[email protected]")
        )
      ),
      toJson(
        Map(
          "name"-> toJson("Kiki"),
          "age"-> toJson(25),
          "email"-> JsNull
        )
      )
    )
  )
)

    Json序列化

    將JsValue轉成Json字符串形式很容易: 
?
1
valjsonString:String =Json.stringify(jsValue)

    其它選擇

    上面討論的基於類型的選擇是推薦的形式,當然也不會限制你使用其它JSON庫。 
    
    例如,下面是一小段演示怎樣將純Scala對象轉成JSON 對象,通過綁定的,基於反射的Jerkson。 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
importcom.codahale.jerkson.Json._
 
valjson =generate(
  Map(
    "url"-> "http://nytimes.com",
    "attributes"-> Map(
      "name"-> "nytimes",
      "country"-> "US",
      "id"-> 25
    ),
    "links"-> List(
      "http://link1",
      "http://link2"
    )
  )
)

    處理Json請求


    處理Json請求 

        一個 JSON 請求是一個使用 request body 搭載經驗證的JSON內容的 HTTP 請求.它必須指定 Content-Type 爲text/json或application/json mime類型。 

    默認Action使用any content body parser,讓你以JSON取值得request body 值(實際上是JsValue): 
?
1
2
3
4
5
6
7
8
9
10
11
defsayHello =Action { request =>
  request.body.asJson.map { json =>
    (json \ "name").asOpt[String].map { name =>
      Ok("Hello "+ name)
    }.getOrElse {
      BadRequest("Missing parameter [name]")
    }
  }.getOrElse {
    BadRequest("Expecting Json data")
  }
}

    更好的方法是自定義BodyParser,請求Play直接將body解析爲JSON: 
?
1
2
3
4
5
6
7
defsayHello =Action(parse.json) { request =>
  (request.body \ "name").asOpt[String].map { name =>
    Ok("Hello "+ name)
  }.getOrElse {
    BadRequest("Missing parameter [name]")
  }
}

    注意:當使用JSON body parser的時候,request.body的值直接做爲一個經驗證的JsValue值。 

    你可以通過在命令行中用curl測試: 
?
1
2
3
4
5
curl
  --header "Content-type: application/json"
  --request POST
  --data '{"name": "Guillaume"}'
  http://localhost:9000/sayHello

    返回: 
?
1
2
3
4
5
HTTP/1.1200OK
Content-Type:text/plain; charset=utf-8
Content-Length:15
 
Hello Guillaume

    返回JSON響應


    前面的一些例子,我們接收JSON請求,但我們返回的是text/plain響應。 
    讓我們更改爲一個有效的HTTP響應: 
?
1
2
3
4
5
6
7
8
9
10
11
defsayHello =Action(parse.json) { request =>
  (request.body \ "name").asOpt[String].map { name =>
    Ok(toJson(
      Map("status"-> "OK""message"-> ("Hello "+ name))
    ))
  }.getOrElse {
    BadRequest(toJson(
      Map("status"-> "KO""message"-> "Missing parameter [name]")
    ))
  }
}

    現在它返回: 
?
1
2
3
4
5
HTTP/1.1200OK
Content-Type:application/json; charset=utf-8
Content-Length:43
 
{"status":"OK","message":"Hello Guillaume"}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章