play2 json

JSON处理主要用到:

play.api.libs.json

包中的对象和类

 

JsValue及子类:
 JsString
 JsNumber Int,Long,Double 有隐式转换
 JsBoolean 
 JsObject Seq[(String,JsValue)]
 JsArray  Seq[JsValue]做参数
 JsNull  
以上这些代表了json的组成元素 可以直接用以上的类来构建JSON 

 

Json对象提供了一些方便的工具
toJson方法

Scala代码   收藏代码
  1. val product = Json.obj(  
  2.  "name" -> JsString("Blue Paper clips"),  
  3.  "ean" -> JsString("12345432123"),  
  4.  "description" -> JsString("Big box of paper clips"),  
  5.  "pieces" -> JsNumber(500),  
  6.  "manufacturer" -> Json.obj(  
  7.   "name" -> JsString("Paperclipfactory Inc."),  
  8.   "contact_details" -> Json.obj(  
  9.   "email" -> JsString("contact@paperclipfactory.example.com"),  
  10.   "fax" -> JsNull,  
  11.   "phone" -> JsString("+12345654321")  
  12.   )  
  13.  ),  
  14.  "tags" -> Json.arr(  
  15.   JsString("paperclip"),  
  16.   JsString("coated")  
  17.  ),  
  18.  "active" -> JsBoolean(true)  
  19. )  

 

 

如果想将JsValue(及子类对象)转化为String

可以用:

Scala代码   收藏代码
  1. val productJsonString = Json.stringify(product)  //用JsValue的toString方法也可以 会调用这个方法  

 
  

对象到JSON:

toJson方法可用于 String Option[Int] 以及 Map[String,String]
要实现其他类别的 可以继承Writes覆写writes方法

对于case class 也可以用Json提供的方法在运行时生成相应的Writes:

Scala代码   收藏代码
  1. implicit val productWrites = Json.writes[Product]  

 

也可以用Path

 

 

 

JSON到Object:
 前者是Writes 现在是Reads

用JsValue的as方法 Reads由JsPath生成:
此外也可以使用asOpt 那么返回的将是一个Option

Scala代码   收藏代码
  1. implicit val reads:Reads[Product] = (  
  2.  (JsPath \ "ean").read[Long] and  
  3.  (JsPath \ "name").read[String] and  
  4.  (JsPath \ "description").read[String]  
  5. )(Product.apply _)  

 
(用JsPath也可以生成Writes 把read换成write即可)

从String->JsValue 用Json.parse
在request中也可以用request.body.asJson 得到一个Option[JsValue]
如果Action只处理JSON的数据 可以写成:

Scala代码   收藏代码
  1. def postProduct2() = Action(parse.json) { request =>  
  2.  val jsValue = request.body  
  3.  // Do something with the JSON  
  4. }  

 
如果content-type不符合(text/json 或者 application/json)就会直接返回400 Bad Request 可以使用parse.tolerantJson如果没有设置content-type的话

用jsValue的validate方法可以检查是否可以转换(用隐式的Reads作为参数):

Scala代码   收藏代码
  1. val age = jsValue.validate[Int] // == JsError  
  2. val name = jsValue.validate[String] // == JsSuccess(Johnny,)  
  3. import Json._  
  4. val json: JsValue = toJson(Map(  
  5.  "name" -> toJson("Johnny"),  
  6.  "age" -> toJson(42),  
  7.  "tags" -> toJson(List("constructor""builder")),  
  8.  "company" -> toJson(Map(  
  9.  "name" -> toJson("Constructors Inc.")))))  

 

处理:

Scala代码   收藏代码
  1. val name = (json \ "name").as[String]               
  2. val age = (json \ "age").asOpt[Int]  
  3. val companyName = (json \ "company" \ "name").as[String]  
  4. val firstTag = (json \ "tags")(0).as[String]             
  5. val allNames = (json \\ "name").map(_.as[String])  

如果不符合 不会抛出异常 会返回JsUndefined(也是JsValue的子类) 或者也可以用asOpt返回Option
可以用模式匹配处理:

Scala代码   收藏代码
  1. (json \ "name") match {  
  2.  case JsString(name) => println(name)  
  3.  case JsUndefined(error) => println(error)  
  4.  case _ => println("Invalid type!")  
  5. }  

 

 

Format

Reads和Writes可以合并 用Format
Format[T]继承自Reads[T]和Writes[T]
然后使用JsPath的format和formatNullable方法:

Scala代码   收藏代码
  1. import play.api.libs.json._  
  2. import play.api.libs.functional.syntax._  
  3. implicit val productFormat = (  
  4.  (JsPath \ "name").format[String] and  
  5.  (JsPath \ "description").formatNullable[String] and  
  6.  (JsPath \ "purchase_price").format[BigDecimal] and  
  7.  (JsPath \ "selling_price").format[BigDecimal]  
  8.     )(PricedProduct.apply, unlift(PricedProduct.unapply))  

或者用现有的Reads和Writes:

Scala代码   收藏代码
  1. implicit val productFormat = Format(productReads, productWrites)  

对于case class 也可以用运行时生成的方式:

Scala代码   收藏代码
  1. implicit val productFormat = Json.format[PricedProduct]  

这种方式是用scala macro生成的 类型安全 对应的还有Json.reads()和Json.writes

  
  

检查

检查: 可以在reads中写规则 这些规则来自:play.api.libs.json.ConstraintReads

Scala代码   收藏代码
  1. implicit val companyReads: Reads[Company] = (  
  2. (JsPath \ "name").read[String] and  
  3. (JsPath \ "contact_details").read(  
  4.  (  
  5.   (JsPath \ "email").readNullable[String](email) and  
  6.   (JsPath \ "fax").readNullable[String](minLength[String](10)) and  
  7.   (JsPath \ "phone").readNullable[String](minLength[String](10))  
  8.  )(Contact.apply _))  
  9. )(Company.apply _)  

验证用JsValue的validate方法 和Form的bindFromRequest类似:

Scala代码   收藏代码
  1. def save = Action(parse.json) { implicit request =>  
  2.  val json = request.body  
  3.  json.validate[Product].fold(  
  4.   valid = { product =>  
  5.    Product.save(product)  
  6.    Ok("Saved")  
  7.     },  
  8.   invalid = {  
  9.    errors => BadRequest(JsError.toFlatJson(errors))  
  10.   })  
  11. }  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值