Scala Json隐式读取:类型不匹配?
我使用的是Play 2.3.4,我定义了一个简单的模型类:Scala Json隐式读取:类型不匹配?,scala,playframework,implicit,Scala,Playframework,Implicit,我使用的是Play 2.3.4,我定义了一个简单的模型类: case类用户( @身份证 id:Int, 名称:String )扩展模型 对象用户{ def find()={/*此处有一些代码*/} 隐式对象UserFormat扩展格式[用户]{ def reads(json:JsValue)=用户( (json \“id”)。作为[Int], (json \“name”)。作为[字符串] ) def写入(user:user)=JsObject(Seq(“id”->id,“name”->name)
case类用户(
@身份证
id:Int,
名称:String
)扩展模型
对象用户{
def find()={/*此处有一些代码*/}
隐式对象UserFormat扩展格式[用户]{
def reads(json:JsValue)=用户(
(json \“id”)。作为[Int],
(json \“name”)。作为[字符串]
)
def写入(user:user)=JsObject(Seq(“id”->id,“name”->name))
}
}
这很简单。但我得到了一个编译错误:
Error:(31, -1) Play 2 Compiler:
/Users/asheshambasta/code/finit/app/models/users/User.scala:31: type mismatch;
found : models.devices.User
required: play.api.libs.json.JsResult[models.users.User]
我做错了什么?上面的代码有几个问题。您收到的编译错误是因为
reads(json:JsValue)
应该返回JsResult
,而不是模型。这是因为在定义读取时需要考虑失败id
和name
在writes
中还需要是user.id
和user.name
。这将汇编:
object User {
implicit object UserFormat extends Format[User] {
def reads(json: JsValue) = JsSuccess(User(
(json \ "id").as[Int],
(json \ "name").as[String]
))
def writes(user: User) = Json.obj("id" -> user.id, "name" -> user.name)
}
}
但是,如果JSON中有错误,这将引发异常,因为as[T]
不安全
scala> val testJs = Json.parse("""{"id":"2", "name": "test"}""")
testJs: play.api.libs.json.JsValue = {"id":"2","name":"test"}
scala> testJs.validate[User]
play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(error.expected.jsnumber,WrappedArray())))))
以这种方式为简单对象定义读取
几乎总是不值得的,使用JSON组合符可以更好地完成
object User {
implicit val reads: Reads[User] = (
(__ \ "id").read[Int] and
(__ \ "name").read[String]
)
implicit val writes: Writes[User] = (
(__ \ "id").write[Int] and
(__ \ "name").write[String]
)
}
JSON组合器不会像第一段代码那样抛出异常,它们会在验证时将所有错误累积到JsResult
中。在这样一个简单的情况下,JSON inception会更好:
object User {
implicit val format: Format[User] = Json.format[User]
}
还有Json.reads[T]
和Json.writes[T]
宏,以防您需要一些自定义的reads
而不是writes
或其他方式。回答得好,非常感谢。它解决了我的问题,也有助于使事情更清楚。