play Framework play json

来源:互联网 发布:淘宝网店挣钱吗 编辑:程序博客网 时间:2024/04/27 23:04

   概述


    使用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("bob@gmail.com")
        )
      ),
      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("bob@gmail.com")
        )
      ),
      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"}
0 0
原创粉丝点击